Dave Maple
Dave Maple

Reputation: 8402

JSF -- Filter for javax.faces.resource text replacements

I'm working with Tomcat7 on JSF 2.17 Mojarra. I'd like to place a servlet filter in front of CSS and Javascript requests to /javax.faces.resource/* to rewrites certain text references in our development and rc environments. I don't seem to be able to alter these CSS and Javascript files using a traditional servlet filter. Is there some other way to accomplish this?

For example, I'm looking to replace references to urls found inside the CSS files from: prod.ourdomain.com to dev.ourdomain.com

something like that. Thanks!

Upvotes: 3

Views: 796

Answers (1)

BalusC
BalusC

Reputation: 1108642

You basically need to override HttpServletResponse#getOutputStream() with a custom ServletOutputStream which writes to a local buffer and then do a string replacement in there and finally write the modified string to the response. This is quite some code, so here are some helpful classes to assist you further:

Then you can basically implement the filter as follows:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
    if (((HttpServletRequest) request).getRequestURI().endsWith(".css.xhtml")) { // If you use *.xhtml as JSF mapping.
        BufferedHttpServletResponse bufferedResponse = new BufferedHttpServletResponse(((HttpServletResponse) response);
        chain.doFilter(request, bufferedResponse);
        String string = new String(bufferedResponse.getBuffer(), response.getCharacterEncoding());
        string = string.replace("http://prod.ourdomain.com", "http://dev.ourdomain.com");
        response.getWriter().write(string);
    }
    else {
        chain.doFilter(request, response);
    }
}

This is however open for further optimization. Instead of buffering the entire response, you could also perform the job inside the custom output stream and buffer only the characters starting with http://prod.ourdomain.com, and then discard it and write the new string instead and then continue.


Update: an entirely different alternative, after all actually better, is to use EL straight in the CSS files. CSS resource requests as performed by JSF <h:outputStylesheet> namely by default supports EL in CSS files. For example,

someSelector {
    background: url("http://#{staging.dev ? 'dev' : 'prod'}.ourdomain.com/image.png");
}

Upvotes: 3

Related Questions