Servlet Response wrapper to add getHeaderNames and

2019-07-11 21:37发布

Since Servlet 3.0, HttpServletResponse#getHeaderNames() and HttpServletResponse#getHeaders() has been available. However, I'm using an older spec, specifically Servlet 2.4.

Having looked at the resource, How can I get the HTTP status code out of a ServletResponse in a ServletFilter?, I got an idea of how to write a wrapper. If I understand it right, I have to use setHeader() to facilitate the creation of getHeaderNames() and getHeaders(). I think I have a solid footing on how to store the headers to simulate the usage of these missing methods.

The problem is the filter which leverages this wrapper does not seem to be calling setHeader() automatically. I don't get it. I presume sincegetStatus() is working properly, I'm expecting setHeader() to behave in the same fashion. Specifically, I'm looking to print out all the response headers, after calling chain.doFilter(). I'm not sure what I'm doing wrong here. Maybe there is something wrong with how I'm storing header name-value pairs.

I would appreciate any help. Thank you.

public class ServletResponseWrapper extends HttpServletResponseWrapper {

    private int httpStatus = SC_OK;
    private HashMap<String, String> hashMapHeaders = new HashMap<String, String>();

    public ServletResponseWrapper(HttpServletResponse response) {
        super(response);
    }

    @Override
    public void sendError(int sc) throws IOException {
        httpStatus = sc;
        super.sendError(sc);
    }

    @Override
    public void sendError(int sc, String msg) throws IOException {
        httpStatus = sc;
        super.sendError(sc, msg);
    }


    @Override
    public void setStatus(int sc) {
        httpStatus = sc;
        super.setStatus(sc);
    }

    public int getStatus() {
        return httpStatus;
    }

    @Override
    public void sendRedirect(String location) throws IOException {
        httpStatus = SC_MOVED_TEMPORARILY;
        super.sendRedirect(location);
    }

    @Override
    public void setHeader(String name, String value) {
        hashMapHeaders.put(name, value);
        super.setHeader(name, value);
    }

    public String getHeader(String name) {
        return hashMapHeaders.get(name);
    }


    public Enumeration<String> getHeaderNames() {
        Enumeration<String> enumerationHeaderNames = Collections.enumeration(hashMapHeaders.keySet());
        return enumerationHeaderNames;
    }

}

public class ServletResponseWrapperFilter implements Filter {

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

        ServletResponseWrapper servletResponseWrapper = new ServletResponseWrapper( (HttpServletResponse) response );
        chain.doFilter( request, servletResponseWrapper );

        // Process response

        // This works, even though I never explicitly call the setStatus() method
        int status = response.getStatus();

        // This returns NULL because no header values get set; I presume setHeader() gets called implicitly
        Enumeration<String> headerNames = servletResponseWrapper.getHeaderNames();
    }

    public void init(FilterConfig config) throws ServletException {
        //empty
    }

    public void destroy() {
        // empty
    }
}

web.xml file

<display-name>Tomcat App</display-name>

<filter>
    <filter-name>ResponseHeadersFilter</filter-name>
    <filter-class>com.company.filters.ResponseHeadersFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>ResponseHeadersFilter</filter-name>
    <url-pattern>/testfilter.jsp</url-pattern>
</filter-mapping>

I took the vendor's servlet out of the equation. The filter now fires on an empty JSP file. Tomcat is also hooked to a front-end web server, IIS. I disabled IIS. Now, I'm accessing the website directly over Tomcat, via port 8080. Despite all this, I dot see any response headers.

Using Fiddler, the response headers I see are few but existing, namely:

  • (Cache) Date
  • (Entity) Content- Length, Content-Type
  • (Miscellaneous) Server
  • And status response, i.e. HTTP/1.1 200 OK

I can get by without getting response headers in the filter. But the big question I have is this is a bug with Servlet version 2.4 or is there some kind of OS Server and/or Tomcat configuration change I need to enable? Unless there's some Tomcat configuration, I'm led to believe this is likely a bug. Perhaps a clean install using the default configuration of the Tomcat version I'm using, 5.5.28, would resolve the problem, but I cannot attempt that at this time.

0条回答
登录 后发表回答