4

I am attempting to change the Content-Type header in a request and change it to "application/json" before it reaches my spring rest controller. I have created a servlet request wrapper to change the values, but when the request reaches the controller it is still "text/plain". The logging shows that the header value has been changed before hitting doFilter();

Here is my class extending HttpServletRequestWrapper

class HttpServletRequestWritableWrapper extends HttpServletRequestWrapper {
private final Logger logger = org.slf4j.LoggerFactory.getLogger(HttpServletRequestWritableWrapper.class);
private final ByteArrayInputStream decryptedBody;

HttpServletRequestWritableWrapper(HttpServletRequest request, byte[] decryptedData) {
    super(request);
    decryptedBody = new ByteArrayInputStream(decryptedData);
}



@Override
public String getHeader(String name) {
    String headerValue = super.getHeader(name);
    if("Accept".equalsIgnoreCase(name))
    {
        logger.debug("Accept header changing :");
        return headerValue.replaceAll(
                MediaType.TEXT_PLAIN_VALUE, MediaType.APPLICATION_JSON_VALUE
        );
    }
    else if ("Content-Type".equalsIgnoreCase(name))
    {
        logger.debug("Content type change: ");
        return headerValue.replaceAll(MediaType.TEXT_PLAIN_VALUE, MediaType.APPLICATION_JSON_VALUE);
    }
    return headerValue;
}

@Override
public Enumeration<String> getHeaderNames() {
    return super.getHeaderNames();
}

@Override
public String getContentType() {
    String contentTypeValue = super.getContentType();
    if (MediaType.TEXT_PLAIN_VALUE.equalsIgnoreCase(contentTypeValue)) {
        logger.debug("Changing on getContentType():");
        return MediaType.APPLICATION_JSON_VALUE;
    }
    return contentTypeValue;
}


@Override
public BufferedReader getReader() throws UnsupportedEncodingException {
    return new BufferedReader(new InputStreamReader(decryptedBody, UTF_8));
}

@Override
public ServletInputStream getInputStream() throws IOException {
    return new ServletInputStream() {
        @Override
        public int read() {
            return decryptedBody.read();
        }
    };
}

And here is my filter:

@WebFilter(displayName = "EncryptionFilter", urlPatterns = "/*")
public class EncryptionFilter implements Filter {
private final Logger logger = org.slf4j.LoggerFactory.getLogger(EncryptionFilter.class);

@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    byte[] data = "{\"currentClientVersion\":{\"majorElement\":\"1\",\"minorElement\":\"2\"}}".getBytes();

    logger.debug("data string " + data.toString());

    logger.debug("Content-type before: " + servletRequest.getContentType());

    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletRequestWritableWrapper requestWrapper = new HttpServletRequestWritableWrapper(request, data);
    //logger.debug("Accept Header: " + requestWrapper.getHeader("Accept"));
    //logger.debug("Content-Type: " + requestWrapper.getHeader("Content-Type"));
    //logger.debug("Contenttype" + requestWrapper.getContentType());

    filterChain.doFilter(requestWrapper, servletResponse);


}

@Override
public void destroy() {

}


}

1 Answer 1

3

It appears that the getHeaders method was being called somewhere else after my filter and not returning the headers with my updated values.

I added this override in my HttpServletRequestWrapper and it is now working:

@Override
public Enumeration<String> getHeaders(String name) {
    List<String> headerVals = Collections.list(super.getHeaders(name));
    int index = 0;
    for (String value : headerVals) {
        if ("Content-Type".equalsIgnoreCase(name)) {
            logger.debug("Content type change: ");
            headerVals.set(index, MediaType.APPLICATION_JSON_VALUE);
        }

        index++;
    }

    return Collections.enumeration(headerVals);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.