How to handle request header with Filter

Asked

Viewed 896 times

3

How to change, remove or add a header of a request in a web application using Filter?

1 answer

3


To recover a header of the requisition HTTP you can use the methods getHeader, getHeaders, in addition to other utilities such as getDateHeader

To add or change it is a little more laborious, since directly you can not do it. For this it is necessary a wrapper/Decorator that will have the headers customized, but remember, the original header of the request will not be changed, you are just decorating the request and keeping in this wrapper the headings changed and included.

To facilitate is already available a wrapper basis that you can extend it, the HttpServletRequestWrapper. From it we will change the form that headers are obtained, so we will overwrite getHeader and getHeaderNames.

So let’s build a CustomHttpServletRequestWrapper, something like this:

public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {

    private final Map<String, String> headers = new HashMap<>();

    public CustomHttpServletRequestWrapper(final HttpServletRequest request) {
        super(request);
    }

    @Override
    public Enumeration<String> getHeaderNames() {
        final HttpServletRequest request = (HttpServletRequest) this.getRequest();
        final List<String> list = new ArrayList<>();

        list.addAll(Collections.list(request.getHeaderNames()));
        list.addAll(headers.keySet());

        return Collections.enumeration(list);
    }

    @Override
    public String getHeader(final String name) {
        if (headers.containsKey(name)) {
            return headers.get(name);
        }
        return super.getHeader(name);
    }

    public void addHeader(final String name, final String value) {
        headers.put(name, value);
    }

}

Note that we are using a map, so I am assuming that we will have only one value for each header name, the key map. You can add another type of data to allow repeated names for headers, if necessary.

In your filter would look something like this:

@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
    if (request instanceof HttpServletRequest) {
        final HttpServletRequest httpRequest = (HttpServletRequest) request;
        final CustomHttpServletRequestWrapper wrapper = new CustomHttpServletRequestWrapper(httpRequest);
        wrapper.addHeader("CUSTOM-HEADER", "value");
        chain.doFilter(wrapper, response);
    } else {
        chain.doFilter(request, response);
    }
}

This wrapper considers only requisitions HTTP, ie, that by default have headers. If you need not only requests HTTP, but all the others ServletRequest take a look at ServletRequestWrapper, you will be able to keep headers for them also in a similar way as we did in CustomHttpServletRequestWrapper.

  • @Did Luidne succeed with this approach? Need any other help? If it helped, consider accepting the answer. Thank you

  • I tested and did not change the header that I chose (SOAPAction). This is my question regarding a Java Web application migration to another Java application server. Glassfish for Wildfly. Where the former accepts header requests SOAPAction with content and the second only accepts without content. This change in the header would not break compatibility in production applications that send SOAPAction with content.

  • @Luídne then man, as said in the reply, you can not change the headers of request original, what we can do is encapsulate the request and in this wrapper change the headers. Then, you have to ensure that it is the encapsulated request that will reach your other layers/interactions. I don’t know how your application is, if you need to change it is in the application or some component of container, but this is what you can do.

  • I get it. Thanks!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.