Hi Mahesh,
Now i see the code i understand the issue more clearly.
In your case you do not actually need to override the existing
behavior of JSPTemplateProcessor and instead your implementation of
ViewProcessor can be specific to using a servlet context and
RequestDispatcher as you have implemented.
In Jersey you can register two or more ViewProcessor and each will be
called until one of them is capable of resolving a path, so it is sort
of similar to MessageBodyWriter as you point out.
In fact with ViewProcessor the resolve method can return a
RequestDispatcher which is then passed to the writeTo method.
I can make a change such that the functionality for operating on a
RequestDispatcher as encapsulated in the JSPTemplateProcessor.writeTo
method is publicly available:
For example:
public static void writeTo(RequestDispatcher d, Viewable
viewable, OutputStream out) throws IOException {
// Commit the status and headers to the HttpServletResponse
out.flush();
d = new RequestDispatcherWrapper(d, basePath, hc, viewable);
try {
d.forward(requestInvoker.get(), responseInvoker.get());
} catch (Exception e) {
throw new ContainerException(e);
}
}
I anyway need to do for for the scalate plugin so there is no
dependency on a private API.
Paul.
On Mar 15, 2010, at 3:42 PM, Mahesh Venkat wrote:
> Thanks Paul. I just implemented #2 approach: Developed a custom
> JSPTemplateProcessor and it works:
> The lingering question I have is, if there are two
> JSPTemplateProcessor, what is the order in which they are picked up
> during runtime? Is it similar to the multiple MessageBodyWriter logic?
>
> My custom JSPTemplateProcessor extends the JSPTemplateProcessor and
> overrides the resolve method():
> Here is the updated resolve() method:
>
> public String resolve(String path) {
> if (servletContext == null)
> return null;
>
> if (basePath != "")
> path = basePath + path;
>
> try {
> if (servletContext.getResource(path) != null) {
> return path;
> } else {
> // check if the entry exists in web.xml through the
> RequestDispatcher
> ServletContext jspContext =
> sc.getServletContext().getContext(path);
> if (jspContext != null) {
> RequestDispatcher jspReqDispatcher =
> sc.getServletContext().getRequestDispatcher(path);
> if (jspReqDispatcher != null)
> {
> return path;
> }
> }
> RequestDispatcher reqDispatcher =
> servletContext.getRequestDispatcher(path);
> if (reqDispatcher != null)
> {
> return path;
> }
> }
>
> if (!path.endsWith(".jsp")) {
> path = path + ".jsp";
> if (servletContext.getResource(path) != null) {
> return path;
> }
> }
> } catch (MalformedURLException ex) {
> // TODO log
> }
>
> return null;
> }
>
> I tested this logic it works.
>
> Regards
> --Mahesh
>
> On Mon, Mar 15, 2010 at 1:05 AM, Paul Sandoz <Paul.Sandoz_at_sun.com>
> wrote:
>
> On Mar 14, 2010, at 6:33 AM, Mahesh Venkat wrote:
>
> Hi Paul,
>
> I invoked the pre-compiled jsp as regular web application url from
> the browser and it is getting resolved successfully to the pre-
> compiled jsp class.
>
> The JSP is pre-compiled using Apache Jasper. The jsp class file is
> packaged as a jar and deployed in the standard WEB-INF/lib directory
> of a JBoss web app directory.
> As part of this package and deployment, Jasper also generates the
> web.xml fragments for the servlet mapping for the jsp class and it
> is added to the target web.xml as a servlet map.
>
> For example:
> <servlet-mapping>
> <servlet-
> name>org.apache.jsp.oauth.oauth_005fuser_005fauthorization_jsp</
> servlet-name>
> <url-pattern>/oauth/oauth_user_authorization.jsp</url-pattern>
> </servlet-mapping>
>
>
> OK, that explains why the resources cannot be detected.
>
>
>
> In the web.xml, I have defined a value for the JSPTemplatesBasePath
> <!--init-param>
> <param-
> name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
> <param-value>oauth</param-value>
> </init-param -->
> <!-- init-param>
> <param-
> name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
> <param-value>/(images|js|styles|(oauth/))/.*</param-
> value>
> </init-param -->
>
> The package name for compiled jsp in Tomcat is:
> /**
> * The default package name for compiled jsp pages.
> */
> public static final String JSP_PACKAGE_NAME =
>
> System.getProperty("org.apache.jasper.Constants.JSP_PACKAGE_NAME",
> "org.apache.jsp.");
>
>
>
> JBoss AS 4/Tomcat 5.5 is conforming to JSP 2.0
>
> The javax.servlet.ServletContext.getResource("ViewTemplate.jsp") or
> javax.servlet.ServletContext.getResourceAsStream("ViewTemplate.jsp")
> that is used to get the
>
>
> physical location of the jsps do not work if the physical jsp's
> aren't there (this is the
> case with precomiled jsp's), it always returns null.
>
> The Servlet API (http://java.sun.com/javaee/5/docs/api/) is not
> exactly clear in it's
>
>
> intended behavior, I would expect that getResource and
> getResourceAsStream would take the servlet mappings in web.xml into
> account, but apparently they don't.
> Perhaps we should implement additional logic in the
> ViewableMessageBodyWriter.java, something along the following lines:
> http://n2.nabble.com/Anyone-tried-pre-compile-JSP-pages-td3220104.html
>
>
> The logic would be required in JSPTemplateProcessor that resolves a
> path to to a JSP.
>
> Since this is specialized behavior based on the JSP compiler you are
> using, i recommend two approaches:
>
> 1) If possible, distribute the JSPs. If the servlets have precedence
> this should be OK.
> That would be equivalent to defining a mapping.
>
> 2) Copy the code from JSPTemplateProcessor and adapt it for the
> needs of compiled JSPs as how Apache Jasper
> works.
>
> I am reluctant to add a mapping solution for this case if either 1)
> or 2) work as many app servers now have dynamic JSP compilation
> built in.
>
> Paul.
>
>
> Jboss Tomcat fixed a bug for servletContext.getResource() in 2005: https://issues.apache.org/bugzilla/show_bug.cgi?id=36534
>
>
> Here is the detail error stack:
>
> 10:17:57,816 ERROR [[JerseySpringRestServlet]] Servlet.service() for
> servlet JerseySpringRestServlet threw exception
> java.io.IOException: The template name, /oauth/
> oauth_user_authorization.jsp, could not be resolved to a fully
> qualified template name
> at
> com
> .sun
> .jersey
> .server
> .impl
> .template
> .ViewableMessageBodyWriter.writeTo(ViewableMessageBodyWriter.java:76)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .template
> .ViewableMessageBodyWriter.writeTo(ViewableMessageBodyWriter.java:58)
> at
> com
> .sun
> .jersey.spi.container.ContainerResponse.write(ContainerResponse.java:
> 266)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl._handleRequest(WebApplicationImpl.java:810)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:736)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:727)
> at
> com
> .sun
> .jersey.spi.container.servlet.WebComponent.service(WebComponent.java:
> 368)
> at
> com
> .sun
> .jersey
> .spi
> .container.servlet.ServletContainer.service(ServletContainer.java:452)
> at
> com
> .sun
> .jersey
> .spi
> .container.servlet.ServletContainer.service(ServletContainer.java:633)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
> at
> org
> .apache
> .catalina
> .core
> .ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
> 290)
> at
> org
> .apache
> .catalina
> .core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
> at
> com
> .yodlee
> .oauth.filter.OAuthServletFilter.filter(OAuthServletFilter.java:237)
> at
> com
> .yodlee
> .oauth.filter.OAuthServletFilter.doFilter(OAuthServletFilter.java:198)
> at
> org
> .apache
> .catalina
> .core
> .ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
> 235)
> at
> org
> .apache
> .catalina
> .core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
> at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal
> (CharacterEncodingFilter.java:96)
> at
> org
> .springframework
> .web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:
> 76)
> at
> org
> .apache
> .catalina
> .core
> .ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
> 235)
> at
> org
> .apache
> .catalina
> .core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
> at
> org
> .jboss
> .web
> .tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
> at
> org
> .apache
> .catalina
> .core
> .ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
> 235)
> at
> org
> .apache
> .catalina
> .core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
> at
> org
> .apache
> .catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:
> 230)
> at
> org
> .apache
> .catalina.core.StandardContextValve.invoke(StandardContextValve.java:
> 175)
> at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke
> (SecurityAssociationValve.java:182)
> at
> org
> .jboss
> .web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
> at
> org
> .apache
> .catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
> at
> org
> .apache
> .catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
> at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke
> (CachedConnectionValve.java:157)
> at
> org
> .apache
> .catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:
> 109)
> at
> org
> .apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:
> 262)
> at
> org
> .apache.coyote.http11.Http11Processor.process(Http11Processor.java:
> 844)
> at org.apache.coyote.http11.Http11Protocol
> $Http11ConnectionHandler.process(Http11Protocol.java:583)
> at org.apache.tomcat.util.net.JIoEndpoint
> $Worker.run(JIoEndpoint.java:446)
> at java.lang.Thread.run(Thread.java:619)
>
>
> Thanks
> --Mahesh
>
> On Wed, Mar 10, 2010 at 12:59 AM, Paul Sandoz <Paul.Sandoz_at_sun.com>
> wrote:
> Hi Mahesh,
>
> Do you know if compiled JSPs are visible to the web application,
> namely can one find them by doing:
>
> servletContext.getResource( path)
>
> ?
>
> If not then this might be an issue with JBoss. There should be a
> correspondence between such resources and being able to create a
> RequestDisptacher to forward to such a resource.
>
> Can you send me a reproducible test case? preferably a maven-based
> project.
>
> Paul.
>
>
> On Mar 9, 2010, at 4:07 PM, Mahesh Venkat wrote:
>
> Hi,
>
> I have two identical JBoss 4.2.0 environments with Jersey 1.1.5 In
> one of them I use jsp as is, while in anther environment I have pre-
> compiled jsp. The Viewable interface is unable to resolve the pre-
> compiled jsp.
> My jsp path is /foo/bar.jsp
>
> I have the following in web.xml:
> <init-param>
> <param-name>com.sun.jersey.
> config.property.JSPTemplatesBasePath</param-name>
> <param-value>/foo</param-value>
> </init-param>
> <init-param>
> <param-
> name>com.sun.jersey.config.feature.NormalizeURI</param-name>
> <param-value>true</param-value>
> </init-param>
> <init-param>
> <param-
> name>com.sun.jersey.config.feature.CanonicalizeURIPath</param-name>
> <param-value>true</param-value>
> </init-param>
> <!-- init-param>
> <param-
> name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
> <param-value>/(images|js|styles|(oauth/))/.*</param-
> value>
> </init-param -->
>
> In the code .. I have the following :
>
> ..
>
> String retour = "/bar.jsp";
> return new Viewable(retour, this);
>
> --
> Regards
> --Mahesh
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>
>
>
> --
> Regards
> --Mahesh
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>
>
>
> --
> Regards
> --Mahesh