Search code examples
jsfservlet-filterscontextpath

jsf sevlet-mapping for *.jsp


Is there a way I can tell my application to let every single page (let's say .jsp pages) to go under faces context?

In my web.xml I easly can do a servlet-mapping similar to:

<servlet-mapping>
   <servlet-name>Faces Servlet</servlet-name>
   <url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
   <servlet-name>Faces Servlet</servlet-name>
   <url-pattern>*.jsf</url-pattern>
</servlet-mapping>

Where I can map every url including /faces/ virtual path or ending in .jsf to be processed by the servlet rapresenting the jsf engine.

But what if I want that everything in my application goes under the faces context? I tried adding:

<servlet-mapping>
   <servlet-name>Faces Servlet</servlet-name>
   <url-pattern>*.jsp</url-pattern>
</servlet-mapping>

But it seems that the application crashes immediately:

NAQ Exception in PhaseListener RESTORE_VIEW(1) afterPhase
java.lang.NullPointerException
 at net.sf.jsfcomp.clientvalidators.ValidatorResourceLoader.afterPhase(Unknown Source)
 at org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersAfter(PhaseListenerManager.java:92)
 at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:99)
 at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:70)
 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:139)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
 at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:691)
 at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:469)
 at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:403)
 at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
 at org.apache.myfaces.context.servlet.ServletExternalContextImpl.dispatch(ServletExternalContextImpl.java:419)
 at org.apache.myfaces.application.jsp.JspViewHandlerImpl.renderView(JspViewHandlerImpl.java:211)
 at it.asg.utility.viewhandlers.UrlParameterViewHandler.renderView(UrlParameterViewHandler.java:116)
 at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:41)
 at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:132)
 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:140)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
 at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:691)
 at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:469)
 at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:403)
 at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
 at org.apache.myfaces.context.servlet.ServletExternalContextImpl.dispatch(ServletExternalContextImpl.java:419)
 at org.apache.myfaces.application.jsp.JspViewHandlerImpl.renderView(JspViewHandlerImpl.java:211)
 at it.asg.utility.viewhandlers.UrlParameterViewHandler.renderView(UrlParameterViewHandler.java:116)
 at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:41)
 at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:132)
 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:140)

What's wrong? Is there a way to let faces context work for every page in my app?


Solution

  • That's not possible because *.jsp is to be parsed by the servletcontainer's builtin JspServlet.

    You could in theory use an url-pattern of /*.

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    

    This will in practice however not work (disallowed by the FacesServlet) and it would only add unnecessary overhead to requests which doesn't need to go through the whole JSF lifecycle.

    Try to not think/look for the hard/cumbersome way. Just use *.jsf and if necessary add a security constraint on *.jsp to block direct access to JSP as I suggested in your previous question. That's the common practice.

    Alternatively, you can also upgrade from JSP to Facelets which is XHTML/XML based. This way you can use *.xhtml or even *.html as both the Facelets suffix and the FacesServlet mapping.