title: SpringBoot 2 - OncePerRequestFilter - modify response Headers after processing of Controller
body: <p>Hello I want to modify some of my API's response Headers after I have completed processing (executed logic) and have concluded with an HTTP status code.</p>
  
  <p>For example if the response is 404, then include specific for example <code>Cache-Control</code> Headers example dont cache, or something like that.</p>
  
  <p>I have already 2 <code>OncePerRequestFilter</code> registered, which work fine - but obviously I can not do logic - once the processing is complete. The <code>CacheControlFilter</code> already has logic that adds by default some <code>Cache-Control</code> headers - e.g cache for 15 sec etc. It seems though that this happens (the addition of headers on the response) on a very early stage of the dispatch and when it reaches to the phase of executing the actual <code>Controller/Endpoint</code> and there is an exception or Error that obviously is going to be handled by an advice etc, I can not <code>mutate</code> these already existing headers- that were already added by the filter. </p>
  
  <pre class="lang-java prettyprint-override"><code>
    @Bean
    public FilterRegistrationBean filterOne() {
      Filter filter = new FilterOne();
      return createFilter(filter, "FilterOne",List.of("/*"));
    }
  
    @Bean
    public FilterRegistrationBean cacheControlFilter() {
      Filter filter = new CacheControlFilter();
      return createFilter(filter, "CacheControlFilter", List.of("/*"));
    }
  
    private FilterRegistrationBean createFilter(Filter aFilter, String filterName,
        List&lt;String&gt; urlPatterns) {
      FilterRegistrationBean filterRegBean = new FilterRegistrationBean(aFilter);
      filterRegBean.addUrlPatterns(urlPatterns.toArray(new String[0]));
      filterRegBean.setName(filterName);
      filterRegBean.setEnabled(true);
      filterRegBean.setAsyncSupported(true);
      return filterRegBean;
    }
  </code></pre>
  
  <p>I have already tried, to add an  <code>HttpServletResponseWrapper</code> as indicated on these post <a href="https://mtyurt.net/post/spring-modify-response-headers-after-processing.html" rel="nofollow noreferrer">here</a> and <a href="https://medium.com/@logan.81k/spring-boot-onceperrequestfilter-addheader-a3457a1bfc99" rel="nofollow noreferrer">here</a> on the <code>CacheControlFilter</code> but it does not seem to work. I have also seen a similar S.O thread <a href="https://stackoverflow.com/questions/30702970/spring-modifying-headers-for-every-request-after-processing-in-posthandle?rq=1">here</a>.</p>
  
  <pre class="lang-java prettyprint-override"><code>HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper(response) {
     @Override
     public void setStatus(int sc) {
        super.setStatus(sc);
        handleStatus(sc);
    }
  
   @Override
   @SuppressWarnings("deprecation")
   public void setStatus(int sc, String sm) {
       super.setStatus(sc, sm);
       handleStatus(sc);
   }
  
   @Override
   public void sendError(int sc, String msg) throws IOException {
       super.sendError(sc, msg);
       handleStatus(sc);
    }
  
   @Override
   public void sendError(int sc) throws IOException {
       super.sendError(sc);
       handleStatus(sc);
   }
  
   private void handleStatus(int code) {
      if(code == 404)
           addHeader("Cache-Control, "xxx");
   }
  
  };
  </code></pre>
  
  <p>But the code is not executed at all! So I want to manipulate the Cache-Control headers on the second filter only after though the processing is complete and I am ready to return a response.</p>
  
  <p>I am not sure if the fact that I also have, doing some clean up and setting responses upon errors - mixes things up!</p>
  
  <pre class="lang-java prettyprint-override"><code>@ControllerAdvice
  @Slf4j
  public class GlobalErrorHandler
  </code></pre>
  
  <p>Update: As a note, when my Controller is throwing an Exception or Error, the above <code>GlobalErrorHandler</code> is invoked and there I execute a special handling, returning an <code>error response</code>. What I see though is that <code>magically</code> the response has already the <code>default</code> headers populated by the Filter (CacheControlFilter). So it ends up being a bit weird, I add extra logic,to change the control header and I end up with a response that has the same header 2 times (1 with the value set by the <code>CacheControlFilter</code> and then any special value I am trying to override on the <code>ControllerAdvice</code> </p>
  
  <p>Any tips or help appreciated thanks! I am using Spring Boot <code>2.1.2</code> with <code>Undertow</code> as my underlying servlet container.</p>