-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hi all !
I'm currently working on an integration between Liferay, JBoss and ZK. We ran into some problems with complex UI. Here's a small summary of my analysis :
1. URLEncoder issue
If we use directives such as <style src="./css/custom.css" /> (especially URLs starting with "./"), Liferay raises an exception complaining that the URL is not an absolute one :
13:56:15,329 GRAVE [org.zkoss] (http--0.0.0.0-8080-2) >>java.lang.IllegalArgumentException: URL path must start with a '/' or include '://' >> at com.liferay.portlet.PortletResponseImpl.encodeURL(PortletResponseImpl.java:410) >> at org.zkoss.web.portlet.RenderHttpServletResponse.encodeURL(RenderHttpServletResponse.java:118) >> at org.zkoss.web.servlet.http.Encodes.encodeURL0(Encodes.java:513) >> at org.zkoss.web.servlet.http.Encodes.access$000(Encodes.java:47) >> at org.zkoss.web.servlet.http.Encodes$1.encodeURL(Encodes.java:429) >> at org.zkoss.web.servlet.http.Encodes.encodeURL(Encodes.java:402)
This may be avoided by using full or absolute URLs but it's a bit confusing to have different behaviours between servlet and portlet modes. Anyway, I don't know if it should be considered a ZK or a Liferay issue but I think URLEncoder should at least handle such errors if possible.
2. RenderHttpServletRequest wrapping
ZK wraps RenderRequests to org.zkoss.web.portlet.RenderHttpServletRequest. It may cause exceptions that go like this :
13:56:15,342 ERROR [com.liferay.portal.kernel.servlet.PortletServlet] (http--0.0.0.0-8080-2) javax.portlet.PortletException: javax.servlet.ServletException: Original SevletRequest or wrapped original ServletRequest not passed to RequestDispatcher in violation of SRV.8.2 and SRV.14.2.5.1: javax.portlet.PortletException: javax.servlet.ServletException: Original SevletRequest or wrapped original ServletRequest not passed to RequestDispatcher in violation of SRV.8.2 and SRV.14.2.5.1 >> at org.zkoss.web.portlet.ServletPortletDispatcher.include(ServletPortletDispatcher.java:57) [zweb-6.0.0.jar:] >> at org.zkoss.web.portlet.Portlets.include(Portlets.java:72) [zweb-6.0.0.jar:] >> at org.zkoss.zk.ui.http.DHtmlLayoutPortlet.handleError(DHtmlLayoutPortlet.java:335) [zk-6.0.0.jar:6.0.0] >> at org.zkoss.zk.ui.http.DHtmlLayoutPortlet.doView(DHtmlLayoutPortlet.java:146) [zk-6.0.0.jar:6.0.0]
To avoid this, I tried first to tell JBoss not to strictly test HttpServletRequest's type by setting system property "-Dorg.apache.catalina.STRICT_SERVLET_COMPLIANCE=false".
This leads to another exception wich is shown below :
14:16:58,743 ERROR [portal-web.docroot.html.portal.render_portlet_jsp] (http--0.0.0.0-8080-2) java.lang.ClassCastException: org.zkoss.web.portlet.RenderHttpServletRequest cannot be cast to javax.servlet.ServletRequestWrapper >> at org.apache.catalina.core.ApplicationFilterFactory.createFilterChain(ApplicationFilterFactory.java:164) >> at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:827) >> at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:720) >> at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:657) >> at org.zkoss.web.portlet.ServletPortletDispatcher.include(ServletPortletDispatcher.java:51) >> at org.zkoss.web.portlet.Portlets.include(Portlets.java:72) >> at org.zkoss.zk.ui.http.DHtmlLayoutPortlet.handleError(DHtmlLayoutPortlet.java:335) >> at org.zkoss.zk.ui.http.DHtmlLayoutPortlet.doView(DHtmlLayoutPortlet.java:146)
As an alternative, I rewrote org.zkoss.web.portlet.RenderHttpServletRequest to use standard javax.servlet.http.HttpServletRequestWrapper. Here's my code :
/** * A facade of RenderRequest that implements HttpServletRespose. * * @author tomyeh */ public class RenderHttpServletRequest implements HttpServletRequest { private final RenderRequest _req; private final HttpServletRequest _hreq; private String _enc = "UTF-8"; private final Map<String, String> _attrs = new HashMap<String, String>(8); public static HttpServletRequest getInstance(RenderRequest req) { final HttpServletRequest res; if (req instanceof HttpServletRequest) { res = (HttpServletRequest) req; } else { res = new RenderHttpServletRequest2(req); } // wraps HttpServletRequest to prevent further type checks : return new HttpServletRequestWrapper(res); } ... code unchanged after that ... }
This works great but I cannot forecast potential side effects of such a modification. Would you mind considering casting a glance at these issues and properly correcting them ?
Many thanks in advance and keep doing such a great job with ZK.
Best regards,
Julien.
Hi all,
Issue #1 occurs since Portlet specification requires absolute path. If you are migrating existing zk applications that included relative path to portlets, you can refer to an workaround posted here.
Issue #2 occurs due to requirement of RequestDispatcher stated in Servlet 2.5 specification. This issue is fixed and will be included in the future releases of ZK.
Neil Lee, Engineer
Potix Corporation
Asked: 2012-08-14 03:28:13 +0800
Seen: 466 times
Last updated: Oct 11 '12