3

In my JSF2.1 web application using PrimeFaces 3.4.2, I have added a new web page containing only one view with renderKitId="PRIMEFACES_MOBILE" (PFM 0.9.3). The idea is that a filter redirects requests coming from mobile devices to this page. Unfortunately this filter is completely breaking the css of the mobile page on some mobile devices (yes, not all devices are affected!). When the filter is there, either the redirected calls and the direct ones are broken on affected devices; when the filter is off, everything works fine.

Here the web filter:

public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain)
        throws IOException, ServletException {

    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse resp = (HttpServletResponse) response;

    boolean isMobile = isMobileDevice(req.getHeader("user-agent"));  // utility function

    if (!req.getRequestURI().contains("/mobile/") && isMobile) {
        resp.sendRedirect(req.getContextPath() + "/faces/mobile/index.xhtml");
    } else {
        chain.doFilter(request, response);
    }    
}

The filter doesn't have any mapping in web.xml. Only the annotation @WebFilter("/*") is present. When the path inside the annotation is faked, everything works well.

The xhtml page is ... fairly simple:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:pm="http://primefaces.org/mobile" >
    <h:head>
    </h:head>
    <h:body>
        <f:view renderKitId="PRIMEFACES_MOBILE">
            <pm:page title="Hello World">
                <pm:view id="main">
                    <pm:header title="Header" />
                </pm:view>
            </pm:page>        
        </f:view>    
    </h:body>
</html>

Additional info about the affected devices here. I have no hint about how to debug this. I have looked into the generated html using Firebug, but wasn't able to detect any difference between the working one and the other.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
perissf
  • 15,979
  • 14
  • 80
  • 117

1 Answers1

10

You need to let the filter skip JSF resource requests on CSS/JS/image files.

if (req.getRequestURI().startsWith(req.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) {
    chain.doFilter(request, response);
    return;
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks, I'd never solve this by myself. For the sake of precision, I had to modify a bit the search path by adding "/faces" in between. – perissf Jan 22 '13 at 20:22
  • You're welcome. In all my answers I assume a JSF2 mapping of `*.xhtml`. – BalusC Jan 22 '13 at 20:25
  • +1 on this answer! I learned how to use/write such filter logic by reading many of BalusC's answers here on stackoverflow within the last 1.5 years! Actually, I'm not using (and never used) 'ResourceHandler.RESOURCE_IDENTIFIER', but as always, you can learn so much from 'BalusC'!!! – Howard Jan 22 '13 at 22:37
  • One more thing, forgot to note this... the code you provided in your question (above) looks very much like my code and that's working fine for me, but I do 'skip JSF resource requests on CSS/JS/image files' within the IF block. This answer is definitely good-to-know! Thanks! – Howard Jan 22 '13 at 22:39
  • @BalusC I have a similar problem ( http://stackoverflow.com/questions/26672592/why-does-an-image-in-graphicimage-not-load-fully-primefaces-mobile ). Where do I put this code? – Glory to Russia Nov 02 '14 at 10:24