namalfernandolk namalfernandolk - 1 month ago 7
Java Question

How to update the response Content-Type after Servlet procesing is done using ServeletFilter

I tried to change the ServletResponse Content-Type using ServletFilter. But, the servelet (in my content, AxisServlet) updates that Content-Type when chain.doFilter() calls. But other Response Headers are correctly updated.

I tried setting response headers after doFilter is called. At that time no response header was updated.

Does anyone know a way to update the Content-Type of the ServletResponse after Servelt is completed?

Code :

public class HeaderFilter implements Filter {

private HashMap<String,String> rsCustomHeaders = new HashMap<String,String>();

public void init(FilterConfig config) throws ServletException {

Enumeration<String> initParameterNames = config.getInitParameterNames();

while (initParameterNames.hasMoreElements()) {

String initParameterName = initParameterNames.nextElement();

rsCustomHeaders.put(initParameterName, config.getInitParameter(initParameterName));

}

System.out.println("init().rsCustomHeaders : " + rsCustomHeaders);
}

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

HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;

for (Map.Entry<String, String> rsCustomHeaderEntry : rsCustomHeaders.entrySet()) {
httpServletResponse.addHeader(rsCustomHeaderEntry.getKey(), rsCustomHeaderEntry.getValue());
}

System.out.println("doFilter().encoding :Set Response Headers Done");

chain.doFilter(httpServletRequest, httpServletResponse);

System.out.println("doFilter().HeaderFilter is Done!!!");


}

public void destroy() {
System.out.println("destroy(). : Destroy is called!");
}
}


web.xml

<filter>
<filter-name>HeaderFilter</filter-name>
<filter-class>filters.HeaderFilter</filter-class>
<init-param>
<param-name>content-type</param-name>
<param-value>application/xml; charset=utf-8</param-value>
</init-param>
<init-param>
<param-name>Content_type</param-name>
<param-value>text/xml; charset=utf-8</param-value>
</init-param>
<init-param>
<param-name>rq_content-type</param-name>
<param-value>text/xml; charset=utf-8</param-value>
</init-param>
<init-param>
<param-name>Header-X</param-name>
<param-value>Value-X</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>HeaderFilter</filter-name>
<url-pattern>/services/GradeThreeMath</url-pattern>
</filter-mapping>

Answer

Set content type on the original response. Use HttpServletResponseWrapper with overridden setContentType to wrap response that is passed to child.doFilter. Overridden setContentType should just ignore any attempts to change content type.

The code snippet:

// Setting content type
httpServletResponse.setContentType("you-content-type");
chain.doFilter(httpServletRequest, new HttpServletResponseWrapper(httpServletResponse) {
    @Override
    public void setContentType(final String type) {
        // Ignore any further attempts to change content type
    }
});