You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Ryan Wynn <bi...@gmail.com> on 2006/07/14 21:41:51 UTC

solution to fileupload within a portlet

Hi,

I have a solution that enables me to upload files using
t:inputFileUpload inside a JSR-168 portlet.

The only configuration change that needs to be made is that you must
refer to my extension of MyFacesGenericPortlet in portlet.xml.
Everything else can remain that same.

I've tested it in WebSphere Portal 5.1 with myfaces-everything-1.1.1.

Has this solution already be submitted?  I saw something about using
Portlet Filters.  This one doesn't use any filters.  If not please let
me know which ticket I should attach to.

Thanks,
Ryan

Re: solution to fileupload within a portlet

Posted by Ryan Wynn <bi...@gmail.com>.
On 7/15/06, Ryan Wynn <bi...@gmail.com> wrote:
> On 7/15/06, Matthias Wessendorf <ma...@apache.org> wrote:
> > ...
> > >                         MultipartRequestWrapper wrapper = new MultipartRequestWrapper(
> > >                                         (HttpServletRequest) request, resolveSize(strMaxSize,
> > >                                                         uploadMaxFileSize), resolveSize(strThreshold,
> > >                                                         uploadThresholdSize), strRepo);
> >
> > ...
> > HttpServletRequest in a Portlet container?
>
> Yeah, I know. Apparently, the ActionRequest in IBM's portlet container
> is a HttpServletRequest underneath.  I do not get any errors for this.
>  Not sure if this would throw class cast in other containers.  But
> theoretically, since ActionRequest and PortletRequest are simply
> interfaces, the underlying object can be a HttpServletRequest.  At
> least that's my understanding.
>
> > ...
> > > There were a few other small changes to avoid ClassCastExceptions but
> > > that's basically it.
> >
> > b/c of what?
>
> The other changes I made where to not set the portlet request flag if
> the ActionRequest was a multipart request.  The reason for this was a
> temporary workaround to get around this in LifeCycleImpl
>
> 434         if (PortletUtil.isPortletRequest(facesContext))
> 435         {
> 436             PortletRequest request =
> (PortletRequest)externalContext.getRequest();
> 437             return request.getParameter(MyFacesGenericPortlet.VIEW_ID);
> 438         }
> 439
> 440         String viewId = externalContext.getRequestPathInfo();  //getPathInfo
>
> Since my externalContext.getRequest() is going to return a
> MultipartRequestWrapper, I would get a class cast exception here in
> the LifeCycleImpl because it expects PortletRequest.  To work around,
> I removed the portlet request flag and returned
>
> multipartRequest.getParameter(MyFacesGenericPortlet.VIEW_ID)
>
> from the getRequestPathInfo() method in my overriden externalContext.
>
> I can put the portlet request flag back as long as LifeCycleImpl does
> not assume that getRequest() will return a PortletRequest.  It just
> has to account for the fact that the request may be a
> MultipartRequestWrapper as well.
>
>
> The other sticking point that I needed to work around was this in
> MyFacesGenericPortlet.
>
> 387             ServletFacesContextImpl facesContext =
> (ServletFacesContextImpl)request.
> 388                                                    getPortletSession().
> 389
> getAttribute(CURRENT_FACES_CONTEXT);
>
> It explicity wants a ServletFacesContextImpl but in my case I used my
> own flavor of FacesContext.  So I just added an instanceof check to
> remove the explicit cast and cast appropriately.  My overridden faces
> context also implements ReleaseableExternalContext so the rest of the
> method works.
>
> I think even if IBM's portlet container is the only one that
> implements ActionRequest as a HttpServletRequest it is worth taking a
> look at.  Before the cast to HttpServletRequest is made a check could
> be inserted to see if it's possible.  This would greatly improve the
> ease of use for file uploads in portlet containers that take this
> implementation approach.  If this was incorporated in
> MyFacesGenericPortlet then the only change required to the portlet
> version of
> http://wiki.apache.org/myfaces/Setup_For_File_Uploads
> would be to place the maxsize, threshold, and repository parameters
> inside the portlet.xml instead of web.xml.
>
> Of course it would be great if the solution could apply generically to
> all portlet containers, but I think 1 is better than none.  Just my 2
> cents.
>

Actually, I just noticed this which I did not know even existed.

http://jakarta.apache.org/commons/fileupload/apidocs/org/apache/commons/fileupload/portlet/PortletFileUpload.html

Evidently, commons fileupload has had some support for this since
1.1.

It looks like tomahawk may have only been using 1.0

http://myfaces.apache.org/tomahawk/dependencies.html


>
>
>
>
>
> >
> > -Matthias
> >
>

Re: solution to fileupload within a portlet

Posted by Ryan Wynn <bi...@gmail.com>.
On 7/24/06, Hamid <ha...@yahoo.com> wrote:
>
> That will be nice of you to tell us more about your FileUploadFacesContext
> class !

You can find out more and look at the code at

https://issues.apache.org/jira/browse/MYFACES-434



> --
> View this message in context: http://www.nabble.com/solution-to-fileupload-within-a-portlet-tf1945001.html#a5468053
> Sent from the My Faces - Dev forum at Nabble.com.
>
>

Re: solution to fileupload within a portlet

Posted by Hamid <ha...@yahoo.com>.
That will be nice of you to tell us more about your FileUploadFacesContext
class !
-- 
View this message in context: http://www.nabble.com/solution-to-fileupload-within-a-portlet-tf1945001.html#a5468053
Sent from the My Faces - Dev forum at Nabble.com.


Re: solution to fileupload within a portlet

Posted by Ryan Wynn <bi...@gmail.com>.
On 7/15/06, Matthias Wessendorf <ma...@apache.org> wrote:
> ...
> >                         MultipartRequestWrapper wrapper = new MultipartRequestWrapper(
> >                                         (HttpServletRequest) request, resolveSize(strMaxSize,
> >                                                         uploadMaxFileSize), resolveSize(strThreshold,
> >                                                         uploadThresholdSize), strRepo);
>
> ...
> HttpServletRequest in a Portlet container?

Yeah, I know. Apparently, the ActionRequest in IBM's portlet container
is a HttpServletRequest underneath.  I do not get any errors for this.
 Not sure if this would throw class cast in other containers.  But
theoretically, since ActionRequest and PortletRequest are simply
interfaces, the underlying object can be a HttpServletRequest.  At
least that's my understanding.

> ...
> > There were a few other small changes to avoid ClassCastExceptions but
> > that's basically it.
>
> b/c of what?

The other changes I made where to not set the portlet request flag if
the ActionRequest was a multipart request.  The reason for this was a
temporary workaround to get around this in LifeCycleImpl

434         if (PortletUtil.isPortletRequest(facesContext))
435         {
436             PortletRequest request =
(PortletRequest)externalContext.getRequest();
437             return request.getParameter(MyFacesGenericPortlet.VIEW_ID);
438         }
439
440         String viewId = externalContext.getRequestPathInfo();  //getPathInfo

Since my externalContext.getRequest() is going to return a
MultipartRequestWrapper, I would get a class cast exception here in
the LifeCycleImpl because it expects PortletRequest.  To work around,
I removed the portlet request flag and returned

multipartRequest.getParameter(MyFacesGenericPortlet.VIEW_ID)

from the getRequestPathInfo() method in my overriden externalContext.

I can put the portlet request flag back as long as LifeCycleImpl does
not assume that getRequest() will return a PortletRequest.  It just
has to account for the fact that the request may be a
MultipartRequestWrapper as well.


The other sticking point that I needed to work around was this in
MyFacesGenericPortlet.

387             ServletFacesContextImpl facesContext =
(ServletFacesContextImpl)request.
388                                                    getPortletSession().
389
getAttribute(CURRENT_FACES_CONTEXT);

It explicity wants a ServletFacesContextImpl but in my case I used my
own flavor of FacesContext.  So I just added an instanceof check to
remove the explicit cast and cast appropriately.  My overridden faces
context also implements ReleaseableExternalContext so the rest of the
method works.

I think even if IBM's portlet container is the only one that
implements ActionRequest as a HttpServletRequest it is worth taking a
look at.  Before the cast to HttpServletRequest is made a check could
be inserted to see if it's possible.  This would greatly improve the
ease of use for file uploads in portlet containers that take this
implementation approach.  If this was incorporated in
MyFacesGenericPortlet then the only change required to the portlet
version of
http://wiki.apache.org/myfaces/Setup_For_File_Uploads
would be to place the maxsize, threshold, and repository parameters
inside the portlet.xml instead of web.xml.

Of course it would be great if the solution could apply generically to
all portlet containers, but I think 1 is better than none.  Just my 2
cents.






>
> -Matthias
>

Re: solution to fileupload within a portlet

Posted by Matthias Wessendorf <ma...@apache.org>.
...
>                         MultipartRequestWrapper wrapper = new MultipartRequestWrapper(
>                                         (HttpServletRequest) request, resolveSize(strMaxSize,
>                                                         uploadMaxFileSize), resolveSize(strThreshold,
>                                                         uploadThresholdSize), strRepo);

...
HttpServletRequest in a Portlet container?
...
> There were a few other small changes to avoid ClassCastExceptions but
> that's basically it.

b/c of what?

-Matthias

Re: solution to fileupload within a portlet

Posted by Ryan Wynn <bi...@gmail.com>.
On 7/14/06, Matthias Wessendorf <ma...@apache.org> wrote:
> dunno the ticket,
> but provide your solution here (describtion) and the code at jira

The solution is basically to override the facesContext method in
MyFacesGenericPortlet.

protected FacesContext facesContext(PortletRequest
request,PortletResponse response) {

		if (FileUpload.isMultipartContent((HttpServletRequest) request)) {

			String strMaxSize = getPortletConfig().getInitParameter(
					MAX_FILE_SIZE);

			String strThreshold = getPortletConfig().getInitParameter(
					THRESHOLD_SIZE);

			String strRepo = getPortletConfig().getInitParameter(
					REPOSITORY_PATH);

			MultipartRequestWrapper wrapper = new MultipartRequestWrapper(
					(HttpServletRequest) request, resolveSize(strMaxSize,
							uploadMaxFileSize), resolveSize(strThreshold,
							uploadThresholdSize), strRepo);

			return new FileUploadFacesContext(getPortletContext(), request,
					response, wrapper);

		} else {
			return super.facesContext(request, response);
		}

	}


If a multipart request is detected the MultipartRequestWrapper is used
inside a custom FacesContext.  In this flavor of FacesContext the
getExternalContext().getRequest() returns the MultipartRequestWrapper;
 It stills gets the session values from portletSession.

There were a few other small changes to avoid ClassCastExceptions but
that's basically it.

Ryan

>
> On 7/14/06, Ryan Wynn <bi...@gmail.com> wrote:
> > Hi,
> >
> > I have a solution that enables me to upload files using
> > t:inputFileUpload inside a JSR-168 portlet.
> >
> > The only configuration change that needs to be made is that you must
> > refer to my extension of MyFacesGenericPortlet in portlet.xml.
> > Everything else can remain that same.
> >
> > I've tested it in WebSphere Portal 5.1 with myfaces-everything-1.1.1.
> >
> > Has this solution already be submitted?  I saw something about using
> > Portlet Filters.  This one doesn't use any filters.  If not please let
> > me know which ticket I should attach to.
> >
> > Thanks,
> > Ryan
> >
>
>
> --
> Matthias Wessendorf
>
> further stuff:
> blog: http://jroller.com/page/mwessendorf
> mail: mwessendorf-at-gmail-dot-com
>

Re: solution to fileupload within a portlet

Posted by Matthias Wessendorf <ma...@apache.org>.
dunno the ticket,
but provide your solution here (describtion) and the code at jira

On 7/14/06, Ryan Wynn <bi...@gmail.com> wrote:
> Hi,
>
> I have a solution that enables me to upload files using
> t:inputFileUpload inside a JSR-168 portlet.
>
> The only configuration change that needs to be made is that you must
> refer to my extension of MyFacesGenericPortlet in portlet.xml.
> Everything else can remain that same.
>
> I've tested it in WebSphere Portal 5.1 with myfaces-everything-1.1.1.
>
> Has this solution already be submitted?  I saw something about using
> Portlet Filters.  This one doesn't use any filters.  If not please let
> me know which ticket I should attach to.
>
> Thanks,
> Ryan
>


-- 
Matthias Wessendorf

further stuff:
blog: http://jroller.com/page/mwessendorf
mail: mwessendorf-at-gmail-dot-com