You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pluto-dev@portals.apache.org by Ken Ramirez <kr...@TheJavaThinkTank.org> on 2005/01/25 17:18:32 UTC

We might have a setRenderParameter problem

Hi Guys,

I created a portlet to test the transferring of files from the browser 
to a portlet (using file uploading). In order to convert the data passed 
to the processAction into text, I retrieved the data using 
getPortletInputStream() and then wrote it all out into a StringBuffer. I 
then tried sending the StringBuffer (converted to a String using 
toString), and passed it to setRenderParameter so that I can access it 
from the doView method. In between the processAction and doView method, 
an exception is thrown. I think it's happening in the transferring of 
the parameters from the ActionResponse object to the RenderRequest 
object. The exception is:

java.lang.ArrayIndexOutOfBoundsException: 4096
    at 
org.apache.coyote.http11.InternalOutputBuffer.write(InternalOutputBuffer.java:688)
    at 
org.apache.coyote.http11.InternalOutputBuffer.write(InternalOutputBuffer.java:616)
    at 
org.apache.coyote.http11.InternalOutputBuffer.sendHeader(InternalOutputBuffer.java:496)
    at 
org.apache.coyote.http11.Http11Processor.prepareResponse(Http11Processor.java:1537)
    at 
org.apache.coyote.http11.Http11Processor.action(Http11Processor.java:892)
    at org.apache.coyote.Response.action(Response.java:182)
    at org.apache.coyote.Response.sendHeaders(Response.java:374)
    at org.apache.coyote.tomcat5.OutputBuffer.doFlush(OutputBuffer.java:322)
    at org.apache.coyote.tomcat5.OutputBuffer.close(OutputBuffer.java:283)
    at 
org.apache.coyote.tomcat5.CoyoteResponse.finishResponse(CoyoteResponse.java:477)
    at 
org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:163)
    at 
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
    at 
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
    at 
org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
    at 
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
    at java.lang.Thread.run(Thread.java:534)

However, when I changed the code from using the request/response object 
to use the PortletSession, everything worked as expected. What follows 
is the source code for the portlet. I commented out the session object 
code and left the code that breaks active so that you can test it 
yourself if you wish.

import javax.portlet.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStream;

public class ShowFilePortlet extends GenericPortlet
{
    public void processAction(ActionRequest request, ActionResponse 
response)
            throws PortletException, IOException
    {
        StringBuffer sb = new StringBuffer();
        InputStream is = request.getPortletInputStream();
        for(int i = is.read(); i != -1; i = is.read())
            sb.append((char)i);
       
        PortletSession ps = request.getPortletSession();
        response.setRenderParameter("filedata", sb.toString());
           /* ps.setAttribute("filedata", sb.toString()); */
    }

    public void doView(RenderRequest request, RenderResponse response)
            throws PortletException, IOException
    {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        StringBuffer text = new StringBuffer();
       
        // Retrieve value of filedata parameter.
        /* PortletSession ps = request.getPortletSession();
        String filedata = (String)ps.getAttribute("filedata");
        ps.removeAttribute("filedata"); */
        String filedata = request.getParameter("filedata");
           
        // Create form with "Select New File" button.
        text.append("<p>Please select a file and press the View File 
button.</p>");
       
        text.append("<form method=\"post\" action=\"");
        text.append(response.createActionURL().toString());
        text.append("\" enctype=\"multipart/form-data\">");

        text.append("File: <input type=\"file\" name=\"file\"><br/><br/>");
        text.append("<input type=\"submit\" value=\"View File\">");
       
        text.append("</form>");

        text.append("<hr/>");
       
        if(filedata != null)
            text.append(filedata);

        out.println(text);
    }
}

-- 
*----*----*----*----*----*----*----*----*----*----*----*----
Stay on top of all things to do with JSR-168 Portlet and
Portal development by bookmarking the authority on the
subject: http://community.java.net/portlet
*
* News
* Weblogs
* Community Tips
* Portlet and Portal Projects
* Featured Articles
* And much more
*
*----*----*----*----*----*----*----*----*----*----*----*----
Ken Ramirez
Send mail to: mailto://kramirez@TheJavaThinkTank.org
Check out the website: http://www.TheJavaThinkTank.org
Check out my Blog at: http://weblogs.java.net/blog/ken_ramirez
*----*----*----*----*----*----*----*----*----*----*----*----


Re: We might have a setRenderParameter problem

Posted by Stefan Hepper <st...@apache.org>.
Ken Ramirez wrote:

> Well, what I would have liked to do was pass attach it to the request 
> as an Object, but there is really no way of doing that. So, I then 
> passed it on the Session. However, it's not as elegant, because you 
> have to put it into the session between the two calls, then you have 
> to pull it out from the session, and finally remove it from the session.
>
> Is this the procedure you would have recommended as well?
>
>
> Ken
>
Yes, session is the only way that scales for this large amount of data. 
You cannot pass directly objects from the action to the render phase as 
this would break inthe remote case where these will be two different 
SOAP calls.

Stefan


> Stefan Hepper wrote:
>
>> Ken Ramirez wrote:
>>
>>> Hi Guys,
>>>
>>> I created a portlet to test the transferring of files from the 
>>> browser to a portlet (using file uploading). In order to convert the 
>>> data passed to the processAction into text, I retrieved the data 
>>> using getPortletInputStream() and then wrote it all out into a 
>>> StringBuffer. I then tried sending the StringBuffer (converted to a 
>>> String using toString), and passed it to setRenderParameter so that 
>>> I can access it from the doView method. In between the processAction 
>>> and doView method, an exception is thrown. I think it's happening in 
>>> the transferring of the parameters from the ActionResponse object to 
>>> the RenderRequest object. The exception is:
>>>
>>> java.lang.ArrayIndexOutOfBoundsException: 4096
>>>     at 
>>> org.apache.coyote.http11.InternalOutputBuffer.write(InternalOutputBuffer.java:688) 
>>>
>>>     at 
>>> org.apache.coyote.http11.InternalOutputBuffer.write(InternalOutputBuffer.java:616) 
>>>
>>>     at 
>>> org.apache.coyote.http11.InternalOutputBuffer.sendHeader(InternalOutputBuffer.java:496) 
>>>
>>>     at 
>>> org.apache.coyote.http11.Http11Processor.prepareResponse(Http11Processor.java:1537) 
>>>
>>>     at 
>>> org.apache.coyote.http11.Http11Processor.action(Http11Processor.java:892) 
>>>
>>>     at org.apache.coyote.Response.action(Response.java:182)
>>>     at org.apache.coyote.Response.sendHeaders(Response.java:374)
>>>     at 
>>> org.apache.coyote.tomcat5.OutputBuffer.doFlush(OutputBuffer.java:322)
>>>     at 
>>> org.apache.coyote.tomcat5.OutputBuffer.close(OutputBuffer.java:283)
>>>     at 
>>> org.apache.coyote.tomcat5.CoyoteResponse.finishResponse(CoyoteResponse.java:477) 
>>>
>>>     at 
>>> org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:163)
>>>     at 
>>> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799) 
>>>
>>>     at 
>>> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705) 
>>>
>>>     at 
>>> org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577) 
>>>
>>>     at 
>>> org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684) 
>>>
>>>     at java.lang.Thread.run(Thread.java:534)
>>>
>>> However, when I changed the code from using the request/response 
>>> object to use the PortletSession, everything worked as expected. 
>>> What follows is the source code for the portlet. I commented out the 
>>> session object code and left the code that breaks active so that you 
>>> can test it yourself if you wish.
>>>
>>> import javax.portlet.*;
>>> import java.io.IOException;
>>> import java.io.PrintWriter;
>>> import java.io.InputStream;
>>>
>>> public class ShowFilePortlet extends GenericPortlet
>>> {
>>>     public void processAction(ActionRequest request, ActionResponse 
>>> response)
>>>             throws PortletException, IOException
>>>     {
>>>         StringBuffer sb = new StringBuffer();
>>>         InputStream is = request.getPortletInputStream();
>>>         for(int i = is.read(); i != -1; i = is.read())
>>>             sb.append((char)i);
>>>                PortletSession ps = request.getPortletSession();
>>>         response.setRenderParameter("filedata", sb.toString());
>>>            /* ps.setAttribute("filedata", sb.toString()); */
>>>     }
>>>
>>>     public void doView(RenderRequest request, RenderResponse response)
>>>             throws PortletException, IOException
>>>     {
>>>         response.setContentType("text/html");
>>>         PrintWriter out = response.getWriter();
>>>         StringBuffer text = new StringBuffer();
>>>                // Retrieve value of filedata parameter.
>>>         /* PortletSession ps = request.getPortletSession();
>>>         String filedata = (String)ps.getAttribute("filedata");
>>>         ps.removeAttribute("filedata"); */
>>>         String filedata = request.getParameter("filedata");
>>>                    // Create form with "Select New File" button.
>>>         text.append("<p>Please select a file and press the View File 
>>> button.</p>");
>>>                text.append("<form method=\"post\" action=\"");
>>>         text.append(response.createActionURL().toString());
>>>         text.append("\" enctype=\"multipart/form-data\">");
>>>
>>>         text.append("File: <input type=\"file\" 
>>> name=\"file\"><br/><br/>");
>>>         text.append("<input type=\"submit\" value=\"View File\">");
>>>                text.append("</form>");
>>>
>>>         text.append("<hr/>");
>>>                if(filedata != null)
>>>             text.append(filedata);
>>>
>>>         out.println(text);
>>>     }
>>> }
>>>
>>> -- 
>>> *----*----*----*----*----*----*----*----*----*----*----*----
>>> Stay on top of all things to do with JSR-168 Portlet and
>>> Portal development by bookmarking the authority on the
>>> subject: http://community.java.net/portlet
>>> *
>>> * News
>>> * Weblogs
>>> * Community Tips
>>> * Portlet and Portal Projects
>>> * Featured Articles
>>> * And much more
>>> *
>>> *----*----*----*----*----*----*----*----*----*----*----*----
>>> Ken Ramirez
>>> Send mail to: mailto://kramirez@TheJavaThinkTank.org
>>> Check out the website: http://www.TheJavaThinkTank.org
>>> Check out my Blog at: http://weblogs.java.net/blog/ken_ramirez
>>> *----*----*----*----*----*----*----*----*----*----*----*----
>>>  
>>>
>> Maybe the URL length is restricted to 2k by tomcat. You should not 
>> store that amount of data in render parameters. Render parameter 
>> should define the view state only.
>>
>> Stefan
>
>
>-- 
>*----*----*----*----*----*----*----*----*----*----*----*----
>Stay on top of all things to do with JSR-168 Portlet and
>Portal development by bookmarking the authority on the
>subject: http://community.java.net/portlet
>*
>* News
>* Weblogs
>* Community Tips
>* Portlet and Portal Projects
>* Featured Articles
>* And much more
>*
>*----*----*----*----*----*----*----*----*----*----*----*----
>Ken Ramirez
>Send mail to: mailto://kramirez@TheJavaThinkTank.org
>Check out the website: http://www.TheJavaThinkTank.org
>Check out my Blog at: http://weblogs.java.net/blog/ken_ramirez
>*----*----*----*----*----*----*----*----*----*----*----*----
>  
>


Re: We might have a setRenderParameter problem

Posted by Ken Ramirez <kr...@TheJavaThinkTank.org>.
Well, what I would have liked to do was pass attach it to the request as 
an Object, but there is really no way of doing that. So, I then passed 
it on the Session. However, it's not as elegant, because you have to put 
it into the session between the two calls, then you have to pull it out 
from the session, and finally remove it from the session.

Is this the procedure you would have recommended as well?


Ken

Stefan Hepper wrote:

> Ken Ramirez wrote:
>
>> Hi Guys,
>>
>> I created a portlet to test the transferring of files from the 
>> browser to a portlet (using file uploading). In order to convert the 
>> data passed to the processAction into text, I retrieved the data 
>> using getPortletInputStream() and then wrote it all out into a 
>> StringBuffer. I then tried sending the StringBuffer (converted to a 
>> String using toString), and passed it to setRenderParameter so that I 
>> can access it from the doView method. In between the processAction 
>> and doView method, an exception is thrown. I think it's happening in 
>> the transferring of the parameters from the ActionResponse object to 
>> the RenderRequest object. The exception is:
>>
>> java.lang.ArrayIndexOutOfBoundsException: 4096
>>     at 
>> org.apache.coyote.http11.InternalOutputBuffer.write(InternalOutputBuffer.java:688) 
>>
>>     at 
>> org.apache.coyote.http11.InternalOutputBuffer.write(InternalOutputBuffer.java:616) 
>>
>>     at 
>> org.apache.coyote.http11.InternalOutputBuffer.sendHeader(InternalOutputBuffer.java:496) 
>>
>>     at 
>> org.apache.coyote.http11.Http11Processor.prepareResponse(Http11Processor.java:1537) 
>>
>>     at 
>> org.apache.coyote.http11.Http11Processor.action(Http11Processor.java:892) 
>>
>>     at org.apache.coyote.Response.action(Response.java:182)
>>     at org.apache.coyote.Response.sendHeaders(Response.java:374)
>>     at 
>> org.apache.coyote.tomcat5.OutputBuffer.doFlush(OutputBuffer.java:322)
>>     at 
>> org.apache.coyote.tomcat5.OutputBuffer.close(OutputBuffer.java:283)
>>     at 
>> org.apache.coyote.tomcat5.CoyoteResponse.finishResponse(CoyoteResponse.java:477) 
>>
>>     at 
>> org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:163)
>>     at 
>> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799) 
>>
>>     at 
>> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705) 
>>
>>     at 
>> org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577) 
>>
>>     at 
>> org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684) 
>>
>>     at java.lang.Thread.run(Thread.java:534)
>>
>> However, when I changed the code from using the request/response 
>> object to use the PortletSession, everything worked as expected. What 
>> follows is the source code for the portlet. I commented out the 
>> session object code and left the code that breaks active so that you 
>> can test it yourself if you wish.
>>
>> import javax.portlet.*;
>> import java.io.IOException;
>> import java.io.PrintWriter;
>> import java.io.InputStream;
>>
>> public class ShowFilePortlet extends GenericPortlet
>> {
>>     public void processAction(ActionRequest request, ActionResponse 
>> response)
>>             throws PortletException, IOException
>>     {
>>         StringBuffer sb = new StringBuffer();
>>         InputStream is = request.getPortletInputStream();
>>         for(int i = is.read(); i != -1; i = is.read())
>>             sb.append((char)i);
>>                PortletSession ps = request.getPortletSession();
>>         response.setRenderParameter("filedata", sb.toString());
>>            /* ps.setAttribute("filedata", sb.toString()); */
>>     }
>>
>>     public void doView(RenderRequest request, RenderResponse response)
>>             throws PortletException, IOException
>>     {
>>         response.setContentType("text/html");
>>         PrintWriter out = response.getWriter();
>>         StringBuffer text = new StringBuffer();
>>                // Retrieve value of filedata parameter.
>>         /* PortletSession ps = request.getPortletSession();
>>         String filedata = (String)ps.getAttribute("filedata");
>>         ps.removeAttribute("filedata"); */
>>         String filedata = request.getParameter("filedata");
>>                    // Create form with "Select New File" button.
>>         text.append("<p>Please select a file and press the View File 
>> button.</p>");
>>                text.append("<form method=\"post\" action=\"");
>>         text.append(response.createActionURL().toString());
>>         text.append("\" enctype=\"multipart/form-data\">");
>>
>>         text.append("File: <input type=\"file\" 
>> name=\"file\"><br/><br/>");
>>         text.append("<input type=\"submit\" value=\"View File\">");
>>                text.append("</form>");
>>
>>         text.append("<hr/>");
>>                if(filedata != null)
>>             text.append(filedata);
>>
>>         out.println(text);
>>     }
>> }
>>
>> -- 
>> *----*----*----*----*----*----*----*----*----*----*----*----
>> Stay on top of all things to do with JSR-168 Portlet and
>> Portal development by bookmarking the authority on the
>> subject: http://community.java.net/portlet
>> *
>> * News
>> * Weblogs
>> * Community Tips
>> * Portlet and Portal Projects
>> * Featured Articles
>> * And much more
>> *
>> *----*----*----*----*----*----*----*----*----*----*----*----
>> Ken Ramirez
>> Send mail to: mailto://kramirez@TheJavaThinkTank.org
>> Check out the website: http://www.TheJavaThinkTank.org
>> Check out my Blog at: http://weblogs.java.net/blog/ken_ramirez
>> *----*----*----*----*----*----*----*----*----*----*----*----
>>  
>>
> Maybe the URL length is restricted to 2k by tomcat. You should not 
> store that amount of data in render parameters. Render parameter 
> should define the view state only.
>
> Stefan


-- 
*----*----*----*----*----*----*----*----*----*----*----*----
Stay on top of all things to do with JSR-168 Portlet and
Portal development by bookmarking the authority on the
subject: http://community.java.net/portlet
*
* News
* Weblogs
* Community Tips
* Portlet and Portal Projects
* Featured Articles
* And much more
*
*----*----*----*----*----*----*----*----*----*----*----*----
Ken Ramirez
Send mail to: mailto://kramirez@TheJavaThinkTank.org
Check out the website: http://www.TheJavaThinkTank.org
Check out my Blog at: http://weblogs.java.net/blog/ken_ramirez
*----*----*----*----*----*----*----*----*----*----*----*----


Re: We might have a setRenderParameter problem

Posted by Stefan Hepper <st...@apache.org>.
Ken Ramirez wrote:

> Hi Guys,
>
> I created a portlet to test the transferring of files from the browser 
> to a portlet (using file uploading). In order to convert the data 
> passed to the processAction into text, I retrieved the data using 
> getPortletInputStream() and then wrote it all out into a StringBuffer. 
> I then tried sending the StringBuffer (converted to a String using 
> toString), and passed it to setRenderParameter so that I can access it 
> from the doView method. In between the processAction and doView 
> method, an exception is thrown. I think it's happening in the 
> transferring of the parameters from the ActionResponse object to the 
> RenderRequest object. The exception is:
>
> java.lang.ArrayIndexOutOfBoundsException: 4096
>     at 
> org.apache.coyote.http11.InternalOutputBuffer.write(InternalOutputBuffer.java:688)
>     at 
> org.apache.coyote.http11.InternalOutputBuffer.write(InternalOutputBuffer.java:616)
>     at 
> org.apache.coyote.http11.InternalOutputBuffer.sendHeader(InternalOutputBuffer.java:496)
>     at 
> org.apache.coyote.http11.Http11Processor.prepareResponse(Http11Processor.java:1537)
>     at 
> org.apache.coyote.http11.Http11Processor.action(Http11Processor.java:892)
>     at org.apache.coyote.Response.action(Response.java:182)
>     at org.apache.coyote.Response.sendHeaders(Response.java:374)
>     at 
> org.apache.coyote.tomcat5.OutputBuffer.doFlush(OutputBuffer.java:322)
>     at org.apache.coyote.tomcat5.OutputBuffer.close(OutputBuffer.java:283)
>     at 
> org.apache.coyote.tomcat5.CoyoteResponse.finishResponse(CoyoteResponse.java:477)
>     at 
> org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:163)
>     at 
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
>     at 
> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
>     at 
> org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
>     at 
> org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
>     at java.lang.Thread.run(Thread.java:534)
>
> However, when I changed the code from using the request/response 
> object to use the PortletSession, everything worked as expected. What 
> follows is the source code for the portlet. I commented out the 
> session object code and left the code that breaks active so that you 
> can test it yourself if you wish.
>
> import javax.portlet.*;
> import java.io.IOException;
> import java.io.PrintWriter;
> import java.io.InputStream;
>
> public class ShowFilePortlet extends GenericPortlet
> {
>     public void processAction(ActionRequest request, ActionResponse 
> response)
>             throws PortletException, IOException
>     {
>         StringBuffer sb = new StringBuffer();
>         InputStream is = request.getPortletInputStream();
>         for(int i = is.read(); i != -1; i = is.read())
>             sb.append((char)i);
>        
>         PortletSession ps = request.getPortletSession();
>         response.setRenderParameter("filedata", sb.toString());
>            /* ps.setAttribute("filedata", sb.toString()); */
>     }
>
>     public void doView(RenderRequest request, RenderResponse response)
>             throws PortletException, IOException
>     {
>         response.setContentType("text/html");
>         PrintWriter out = response.getWriter();
>         StringBuffer text = new StringBuffer();
>        
>         // Retrieve value of filedata parameter.
>         /* PortletSession ps = request.getPortletSession();
>         String filedata = (String)ps.getAttribute("filedata");
>         ps.removeAttribute("filedata"); */
>         String filedata = request.getParameter("filedata");
>            
>         // Create form with "Select New File" button.
>         text.append("<p>Please select a file and press the View File 
> button.</p>");
>        
>         text.append("<form method=\"post\" action=\"");
>         text.append(response.createActionURL().toString());
>         text.append("\" enctype=\"multipart/form-data\">");
>
>         text.append("File: <input type=\"file\" 
> name=\"file\"><br/><br/>");
>         text.append("<input type=\"submit\" value=\"View File\">");
>        
>         text.append("</form>");
>
>         text.append("<hr/>");
>        
>         if(filedata != null)
>             text.append(filedata);
>
>         out.println(text);
>     }
> }
>
>-- 
>*----*----*----*----*----*----*----*----*----*----*----*----
>Stay on top of all things to do with JSR-168 Portlet and
>Portal development by bookmarking the authority on the
>subject: http://community.java.net/portlet
>*
>* News
>* Weblogs
>* Community Tips
>* Portlet and Portal Projects
>* Featured Articles
>* And much more
>*
>*----*----*----*----*----*----*----*----*----*----*----*----
>Ken Ramirez
>Send mail to: mailto://kramirez@TheJavaThinkTank.org
>Check out the website: http://www.TheJavaThinkTank.org
>Check out my Blog at: http://weblogs.java.net/blog/ken_ramirez
>*----*----*----*----*----*----*----*----*----*----*----*----
>  
>
Maybe the URL length is restricted to 2k by tomcat. You should not store 
that amount of data in render parameters. Render parameter should define 
the view state only.

Stefan