在日常开发过程中,经常有修改response header的需要。一般有4种方式:
1. 直接在controller的具体method中给ResponseEntity设置CacheControl
package com.example.demo.controller;
import org.springframework.http.CacheControl;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@GetMapping("hello")
public ResponseEntity<String> hello(){
CacheControl noStore = CacheControl.noStore();
return ResponseEntity.ok()
.cacheControl(noStore)
.body("hello");
}
}
-
效果如下:
Screen Shot 2020-04-22 at 12.19.14 PM.png
这种方式适合于给指定的请求添加Cache-Control的header。如果所有请求均需要添加这样的header,通过这种方式比较麻烦。
2 通过@ControllerAdvice注解来修改response header
package com.example.demo.controller;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@GetMapping("hello")
public ResponseEntity<String> hello() {
return ResponseEntity.ok("hello");
}
}
package com.example.demo;
import org.springframework.core.MethodParameter;
import org.springframework.http.CacheControl;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import javax.servlet.http.HttpServletResponse;
@ControllerAdvice
public class HeaderModifierAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
ServletServerHttpResponse ssResp = (ServletServerHttpResponse)serverHttpResponse;
if(ssResp == null || ssResp.getServletResponse() == null) {
return body;
}
// 对于未添加跨域消息头的响应进行处理
HttpServletResponse resp = ssResp.getServletResponse();
resp.setHeader("Cache-Control", "no-store");
return body;
}
}
Screen Shot 2020-04-22 at 12.35.42 PM.png
3 通过Filter来修改response header
package com.example.demo.controller;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@GetMapping("hello")
public ResponseEntity<String> hello() {
return ResponseEntity.ok("hello");
}
}
package com.example.demo.fliter;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
@WebFilter(filterName = "addCacheControlToHeaderFilter", urlPatterns = "/hello")
public class AddCacheControlToHeaderFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse httpServletResponse = (HttpServletResponse)servletResponse;
httpServletResponse.setHeader("Cache-Control", "no-store");
filterChain.doFilter(servletRequest,httpServletResponse);
}
}
Screen Shot 2020-04-22 at 12.19.14 PM.png
4 拦截器来修改response header
package com.example.demo.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
public class AddCacheControlToHeaderInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setHeader("Cache-Control", "no-store");
log.info("AddCacheControlToHeaderInterceptor preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("AddCacheControlToHeaderInterceptor postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("AddCacheControlToHeaderInterceptor afterCompletion");
}
}
package com.example.demo.config;
import com.example.demo.interceptor.AddCacheControlToHeaderInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AddCacheControlToHeaderInterceptor())
.addPathPatterns("/hello")
.excludePathPatterns("/test")
.order(0);
super.addInterceptors(registry);
}
}
Screen Shot 2020-04-22 at 12.19.14 PM.png
网友评论