|
View:
New views
3 Messages
—
Rating Filter:
Alert me
|
|
|
Using a StaticFilter and dispatching to FacesServlet doesn't workIn my web application, I prefer to have FacesServlet mapped to *.html. This has worked fine for me for the last couple of years. Recently, I've tried to add a StaticFilter that looks for static files (i.e. /content/faq.html) and dispatches to those if they're found. If they're not found, I dispatch to the FacesServlet, which doesn't have a <servlet-mapping> in web.xml. This all works great, except that <h:commandLink> seems to need the servlet mapping in order to create its links. If I have the following in my web.xml:
<!-- No servlet-mapping - StaticFilter handles forwarding to "faces" servlet when no static files found --> <!--servlet-mapping> <servlet-name>faces</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping--> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> Links are rendered as /dwr/foo.xhtml instead of /foo.html. Is this a known issue? Is there a better way to do what I'm trying to do (without using a different extension)? Thanks, Matt package org.appfuse.webapp.filter; import org.apache.commons.lang.StringUtils; import org.springframework.util.PatternMatchUtils; import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.util.UrlPathHelper; import javax.servlet.FilterChain; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Iterator; import java.util.Set; /** * A simple filter that allows the application to continue using the .html prefix for actions but also allows * static files to be served up with the same extension. Dojo to serve up its HTML template code. The filter works * on an include/exclude basis where all requests for active pages are redirected by the filter to thee dispatch * servlet. All Dojo related .html requests are allowed to pass straight through to be processed by the servlet * container as per normal. */ public class StaticFilter extends OncePerRequestFilter { private final static String DEFAULT_INCLUDES = "*.html"; private final static String DEFAULT_EXCLUDES = ""; private static final String INCLUDES_PARAMETER = "includes"; private static final String EXCLUDES_PARAMETER = "excludes"; private static final String SERVLETNAME_PARAMETER = "servletName"; private String[] excludes; private String[] includes; private String servletName = null; /** * Read the includes/excludes paramters and set the filter accordingly. */ public void initFilterBean() { String includesParam = getFilterConfig().getInitParameter(INCLUDES_PARAMETER); if (StringUtils.isEmpty(includesParam)) { includes = parsePatterns(DEFAULT_INCLUDES); } else { includes = parsePatterns(includesParam); } String excludesParam = getFilterConfig().getInitParameter(EXCLUDES_PARAMETER); if (StringUtils.isEmpty(excludesParam)) { excludes = parsePatterns(DEFAULT_EXCLUDES); } else { excludes = parsePatterns(excludesParam); } // if servletName is specified, set it servletName = getFilterConfig().getInitParameter(SERVLETNAME_PARAMETER); } private String[] parsePatterns(String delimitedPatterns) { //make sure no patterns are repeated. Set patternSet = org.springframework.util.StringUtils.commaDelimitedListToSet(delimitedPatterns); String[] patterns = new String[patternSet.size()]; int i = 0; for (Iterator iterator = patternSet.iterator(); iterator.hasNext(); i++) { //no trailing/leading white space. String pattern = (String) iterator.next(); patterns[i] = pattern.trim(); } return patterns; } /** * This method checks to see if the current path matches includes or excludes. If it matches includes and * not excludes, it forwards to the static resource and ends the filter chain. Otherwise, it forwards to the * next filter in the chain. * * @param request the current request * @param response the current response * @param chain the filter chain * @throws IOException * @throws ServletException */ public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { UrlPathHelper urlPathHelper = new UrlPathHelper(); String path = urlPathHelper.getPathWithinApplication(request); boolean pathExcluded = PatternMatchUtils.simpleMatch(excludes, path); boolean pathIncluded = PatternMatchUtils.simpleMatch(includes, path); if (pathIncluded && !pathExcluded) { if (logger.isDebugEnabled()) { logger.debug("Forwarding to static resource: " + path); } RequestDispatcher rd = getServletContext().getRequestDispatcher(path); rd.forward(request, response); return; } if (servletName != null) { RequestDispatcher rd = getServletContext().getNamedDispatcher(servletName); rd.forward(request, response); return; } chain.doFilter(request, response); } } |
|
|
Re: Using a StaticFilter and dispatching to FacesServlet doesn't workSo, you just want to do a get request instead of a post, right? Yes you have to use a Servlet to help you implement this or you can add Shale project and do Shale remoting. This is how we got around the problem. Thanks, Calvin Hill return Programmer.someType() On Mar 22, 2007, at 4:00 PM, mraible wrote:
|
|
|
Re: Using a StaticFilter and dispatching to FacesServlet doesn't workmraible wrote:
> In my web application, I prefer to have FacesServlet mapped to *.html. This > has worked fine for me for the last couple of years. Recently, I've tried to > add a StaticFilter that looks for static files (i.e. /content/faq.html) and > dispatches to those if they're found. If they're not found, I dispatch to > the FacesServlet, which doesn't have a <servlet-mapping> in web.xml. This > all works great, except that <h:commandLink> seems to need the servlet > mapping in order to create its links. If I have the following in my > web.xml: > > <!-- No servlet-mapping - StaticFilter handles forwarding to "faces" > servlet when no static files found --> > <!--servlet-mapping> > <servlet-name>faces</servlet-name> > <url-pattern>*.html</url-pattern> > </servlet-mapping--> > > <servlet-mapping> > <servlet-name>dwr-invoker</servlet-name> > <url-pattern>/dwr/*</url-pattern> > </servlet-mapping> > > Links are rendered as /dwr/foo.xhtml instead of /foo.html. Is this a known > issue? Is there a better way to do what I'm trying to do (without using a > different extension)? I'm surprised you had so few problems. I struck a similar issue just this week, as I wrote a variant of Sitemesh applyDecorator that handles JSF "decorator" content when the main page is not JSF (and therefore the servlet that was activated did not have a JSF mapping). The form renderer, however, uses the mapping of the "current" Servlet in order to determine what url to render in the form "action" attribute. In my case (and yours too) the servlet is not actually the FacesServlet so the action attribute is wrong and therefore anything that submits a form breaks (not just commandLink but commandButton too). The form renderer uses JspViewHandlerImpl.getActionURL to determine what url to output as the "action" attribute of the form tag. If this is wrong then of submit of the form bad things obviously happen. But the getActionURL method really assumes that the servlet which was invoked by this request is the FacesServlet which is not always the case here. In particular, it uses ExternalContext.getRequestPathInfo to determine whether the servlet is mapped using extensions or "paths". My workaround was to create a subclass of HttpServletRequestWrapper that fudges the getPathInfo etc. to trick JSF into thinking the JSF servlet was invoked. Regards, Simon |
| Free embeddable forum powered by Nabble | Forum Help |