Spring中为多个RestController端点统一配置Cache-Control
统一为Spring 5 REST接口设置Cache-Control的解决方案
嘿,我明白你现在的困扰——每个@RestController方法都要手动用ResponseEntity设置Cache-Control,代码重复得让人头疼!别担心,Spring 5里有好几种方式能帮你统一配置,彻底告别冗余代码。
方案一:使用HandlerInterceptor全局拦截
拦截器可以在请求处理完成后统一给响应添加Cache-Control头,适合全局范围内的所有接口(或者你指定的路径)。
第一步:编写拦截器类
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; public class CacheControlInterceptor implements HandlerInterceptor { @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 这里可以根据请求路径、处理器类型做精准判断,比如只给@RestController的接口加头 // 设置你需要的Cache-Control策略,比如禁止缓存 response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // 兼容旧浏览器的额外头 response.setHeader("Expires", "0"); response.setHeader("Pragma", "no-cache"); } }
第二步:注册拦截器到Spring配置
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // 指定只拦截你的API路径,比如/api/** registry.addInterceptor(new CacheControlInterceptor()) .addPathPatterns("/api/**"); } }
方案二:使用@ControllerAdvice + ResponseBodyAdvice
这个方案更精准地针对@RestController(或@ResponseBody)的响应,能在返回体写入前修改响应头,非常适合REST接口场景。
import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; // 指定你的API所在的包,只处理该包下的接口 @ControllerAdvice(basePackages = "com.yourproject.api") public class GlobalCacheControlAdvice implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter returnType, Class<?> converterType) { // 返回true表示处理所有@ResponseBody的方法,也可以根据返回类型、注解做筛选 return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<?> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { // 设置Cache-Control头 response.getHeaders().setCacheControl("no-cache, no-store, must-revalidate"); response.getHeaders().setExpires(0); response.getHeaders().setPragma("no-cache"); return body; } }
灵活覆盖全局配置
如果某个接口需要单独设置不同的Cache-Control策略,你依然可以用原来的ResponseEntity方式——ResponseEntity的头会覆盖全局配置的头,完全不影响灵活性。
比如:
@PostMapping("/search") public ResponseEntity<SearchResultDto> search(SearchDto searchDto) { // ...业务逻辑 return ResponseEntity.ok() .cacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES)) .body(searchResult); }
这样这个接口就会使用max-age=600的缓存策略,而不是全局的禁止缓存。
内容的提问来源于stack exchange,提问作者mangei
相关产品推荐
相关产品推荐

