Reputation: 21971
I'm implementing a filter to redirect expired users to a password page.
I'm also using Tuckey URL rewriting to hide the .xhtml extension.
My problem now is how do I set up my filter to only filter JSF pages and not static resources?
Upvotes: 1
Views: 695
Reputation: 1108642
You shouldn't have the need to change the logic of your user filter when you map it in web.xml
after the URL rewrite filter and it is also explicitly dispatched on FORWARD
. This way the incoming request URL/URI will just be the original ones. Filters are namely by default dispatched on REQUEST
and this will miss hits when some other filter before in the chain performs a RequestDispatcher#forward()
call, like the URL rewrite filter does.
<!-- Should be placed *after* URL rewrite filter. -->
<filter-mapping>
<filter-name>yourLoginFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
To make it more specific, you could also just hook the filter to a specific servlet instead of an URL pattern. The below example assumes that you've mapped FacesServlet
on a <servlet-name>
of facesServlet
(note that you still need to keep the forward dispatcher):
<!-- Should be placed *after* URL rewrite filter. -->
<filter-mapping>
<filter-name>yourLoginFilter</filter-name>
<servlet-name>facesServlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Either way, note that in case you'd like to allow original URLs as well (and thus you haven't configured the URL rewrite filter to redirect them to the rewritten URL), then you need to explicitly specify the REQUEST
dispatcher as well as shown above, otherwise the filter won't run when the user directly requests the page using the original URL. In case you don't allow original URLs, just remove <dispatcher>REQUEST</dispatcher>
.
That said, the term "static resources" is somewhat ambiguous in this context. You of course meant to say like CSS/JS/image resources, but the above filters would still cover those managed by JSF via <h:outputStylesheet>
, <h:outputScript>
, etc, all having a /javax.faces.resource/*
URL pattern. You'd best perform an additional check in the filter on the request URL like below:
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
boolean facesResourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER + "/");
if (facesResourceRequest)) {
chain.doFilter(request, response); // Skip JSF resources.
return;
}
// Your original filter code here.
}
Upvotes: 2