While trying to get the JPetstore portlet to work properly in uPortal 2.5 using the Apache Struts Bridge I found some problems with the uPortal request wrappers.
Let me explain, the Struts Bridge uses render parameter _spage to communicate request parameters to Struts.
_spage=/shop/viewCategory.shtml?categoryId=CATS
The embedded portlet url with the _spage request looks like this:
http://locahost:8080/uPortal/tag.37e430d1204c663f.render.userLayoutRootNode.target.101.uP?uP_portlet_action=true&_spage=%2Fshop%2FviewCategory.shtml%3FcategoryId%3DCATS&_sorig=%2Fshop%2Findex.shtml#101
The StrutsPortlet invokes the StrutsServet using a RequestDispatcher object obtained using this path=/shop/viewCategory.shtml?categoryId=CATS
The ServletContext, HttpServletRequest and HttpServletResponse objects are retrieved from ServletContextProvider implemented for uPortal. Then the RequestDispatcher.include() method is called with this HttpServletRequest and HttpServletResponse objects as arguments.
Now in uPortal there are three request wrappers that act on the tomcat ApplicationHttpRequest:
org.jasig.portal.container.servlet.PortletParameterRequestWrapper
org.jasig.portal.container.servlet.ServletRequestImpl
org.jasig.portal.RequestParamWrapper
uPortal wraps the tomcat ApplicationHttpRequest and the constructor for the wrappers in uPortal builds a copy of the parameter map at that point. Subsequently the setQueryParams in ApplicationHttpRequest is called by the ApplicationDispatcher in tomcat. This sets the The query string parameter 'categoryId=CATS' for this request.
Now as per the Servet specification:
SRV.8.1.1 Query Strings in Request Dispatcher Paths
"Parameters specified in the query string used to create the RequestDispatcher take precedence over other parameters of the same name passed to the included servlet. The parameters associated with a RequestDispatcher are scoped to apply only for the duration of the include or forward call."
So at this point the parameters are present in both the query string and the request parameter, they are now merged by tomcat. But the copy of the parameters in the wrapper doesn't reflect the state of the parameters in the tomcat request. So the JPetstore portlet doesn't work and the categoryId parameter is not found.
In addition, I noticed that the the constructor for org.jasig.portal.RequestParamWrapper is incorrect. It access the parameter field before its initialized with any values.
for example
>> boolean isPortletRequest = parameters.containsKey(PortletStateManager.ACTION);
will always be false.
I have attached fixes for both these issues. This is also a fixes a known issue
UP-1226.