Reputation: 523
Lets say I have an Spring REST API which has many, many responses being returned throughout the code.
If I wanted to return two specific headers with every single response I send out, How might I do that in a more intelligent way than manually adding them to every response before returning?
Is there a mechanism which allows me to catch the response before I send it, and add the headers?
EDIT : For future visitors asking this question. None of the answers here will actually result in a working interceptor. I suggest looking elsewhere.
Upvotes: 10
Views: 29550
Reputation: 961
The way I got it to work was using ResponseBodyAdvice as shown in the example linked by Faxy.
Here is my solution for adding cache-control headers to every request:
@ControllerAdvice
public class HeaderModifierAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(final MethodParameter returnType, final Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(final Object body,
final MethodParameter returnType,
final MediaType selectedContentType,
final Class<? extends HttpMessageConverter<?>> selectedConverterType,
final ServerHttpRequest request,
final ServerHttpResponse response) {
response.getHeaders().add("Cache-Control", "no-cache, no-store, must-revalidate");
response.getHeaders().add("Pragma", "no-cache");
response.getHeaders().add("Expires", "0");
return body;
}
}
Upvotes: 11
Reputation: 523
The correct answer is to use a filter. Interceptors are not correct for this, regardless what people online say. Interceptors just don't work as desired.
Working solution is to create a filter as follows :
public class myAwesomeFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.addHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.addHeader("pragma", "no-cache");
filterChain.doFilter(request, response);
}
}
Then, in web.xml - you need the following :
<filter>
<filter-name>sensitiveFormHeaderFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
Upvotes: 21
Reputation: 3733
You can easily do those using Handler Interceptors which allow you to modify the request processing lifecycle within Spring MVC. Interceptors are a very powerful tool that allows us to add functionality to the request processing lifecycle at 3 different points:
I think option 2 will suit your needs.
Then you can write something like this:
public class MyInterceptor extends HandlerInterceptorAdapter {
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
super.postHandle(request, response, handler, modelAndView);
//add your two headers on the response here
}
}
step 2 is to register that interceptor in your configuration file, add the next lines to your XML configuration:
<mvc:interceptors>
<bean Class="your interceptor class">
</mvc:interceptors>
from now on that interceptor will apply for every request.
Upvotes: 1
Reputation: 24
You may use spring interceptors for this purpose. Or there is more generic way to do this which not requires Spring for this. It's filter
Upvotes: -1