0

Why I don't get the value in the method parameter@RequestHeader("Custom-Header"), although I get it in @RequestHeader Map<String,String> headers?

Initially, the request comes to the server without the "Custom-Header", I add it in my filter. After that, the request falls into the method, but the spring cannot insert the header in parameter @RequestHeader("Custom-Header"). Why?

method:

    @PostMapping("/support")
        public SupportView sendEmailToSupport(/*@Validated MessageView supportView,*/
                @RequestHeader Map<String, String> headers, //there is a header
                @RequestHeader(value = CUSTOM_HEADER, required = false) String customHeader) { //but not here
            SupportView supportView = helpDeskService.sendEmailToSupport(null, customHeader);
            return supportView;
        }

filter:

public class HeaderChangerFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        MutableHttpServletRequestWrapper request = new MutableHttpServletRequestWrapper((HttpServletRequest) servletRequest);

        String oldHeaderValue = request.getHeader(OLD_HEADER);
        String newHeaderValue = request.getHeader(CUSTOM_HEADER);

        if (oldHeaderValue != null && newHeaderValue == null) {
            request.putHeader(CUSTOM_HEADER, RequestHeaderUtils.getOldHeaderValue(request));
        }

        filterChain.doFilter(request, servletResponse); //CUSTOM_HEADER has in request headers
    }}

request delegation:

import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class MutableHttpServletRequestWrapper extends HttpServletRequestWrapper {
    // holds a custom header and value mapping
    private final Map<String, String> customHeaders;

    public MutableHttpServletRequestWrapper(HttpServletRequest request){
        super(request);
        this.customHeaders = new HashMap<>();
    }

    public void putHeader(String name, String value){
        this.customHeaders.put(name, value);
    }

    @Override
    public String getHeader(String name) {
        // check the custom headers first
        String headerValue = customHeaders.get(name);

        if (headerValue != null){
            return headerValue;
        }
        // else return from into the original wrapped object
        return ((HttpServletRequest) getRequest()).getHeader(name);
    }

    @Override
    public Enumeration<String> getHeaderNames() {
        // create a set of the custom header names
        Set<String> set = new HashSet<>(customHeaders.keySet());

        // now add the headers from the wrapped request object
        Enumeration<String> e = ((HttpServletRequest) getRequest()).getHeaderNames();
        while (e.hasMoreElements()) {
            // add the names of the request headers into the list
            String n = e.nextElement();
            set.add(n);
        }

        // create an enumeration from the set and return
        return Collections.enumeration(set);
    }
}
3
  • No one knows? Maybe there are suggestions? Commented Apr 2, 2020 at 16:43
  • What does your MutableHttpServletRequestWrapper look like. How does it implement the getHeader method and all of its friends? Commented Apr 2, 2020 at 18:19
  • @M.Deinum pinned. This is just a delegate of HttpServletRequest readable object. Required for adding of my custom header. Commented Apr 2, 2020 at 19:41

1 Answer 1

2

You can override getHeaders() method.

@Override
public Enumeration<String> getHeaders(String name) {
    String values = getHeader(name);
    Set<String> set = Arrays.asList(values.split(",")).stream().collect(Collectors.toSet());
    if (customHeaders.containsKey(name)) {
       return Collections.enumeration(set);
    }
    return super.getHeaders(name);
}
Sign up to request clarification or add additional context in comments.

1 Comment

When should I override method?

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.