Search code examples
javajsfcontent-typeservlet-filters

HttpServletResponse content type null when detecting html file


I'm trying to implement Java servlet filter, that modifies html responses.

doFilter method of my filter class looks like that:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    if (filterConfig == null) {
        return;
    }

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

    String contentType = res.getContentType();

    if (contentType != null && contentType.contains("text/html")) {
        chain.doFilter(req, res);
        // do some modification
    } 
}

For every response I'm trying to figure it out if it's an HTML. If that's the case, I do some modification, but I have the following problem: When requesting jsf file, res.getContentType() returns null (res.getHeader("Content-Type") also returns null). In my browser's developer tools I can see that 'Content-Type' header has value 'text/html; charset=UTF-8', but why does res.getContentType() return null in that case?

Is there any other way to detect HTML response in filter?

EDIT I've added chain.doFilter(req, res) invocation in if clause.

enter image description here


Solution

  • Since JSF uses a servlet, you can only check the content it generated after the chain (you seem to expect it is executed before your filter, but it is not). The reason for this is that the complete filter chain is always executed before the servlets, always, see

    This means that in your doFilter(...) you can only access responses if you access it after the chain.doFilter(..) in your code as can be seen in the first link.

    So unless a filter creates content (which it should not iirc, not real content at least), the content type on the response will always be null before the chain.doFilter() is called (unless a filter e.g. created an authentication/authorisation failure response).

    Effectively your code is doing

    String a=null;
    if (a != null || or a.equals("b") {
       doThing();
    }
    

    It hence seems you have a http://www.xyproblem.info and so you have to rethink your design. (what are you trying to achieve)