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