美文网首页Java
Spring MVC 给response添加Cache-Cont

Spring MVC 给response添加Cache-Cont

作者: 西安法律咨询服务平台与程序员 | 来源:发表于2020-04-26 12:03 被阅读0次

    在日常开发过程中,经常有修改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

    参考文档

    1. SpringMVC 教程 - HTTP 缓存
    2. Spring Boot实战:拦截器与过滤器
    3. [Spring Boot] response header新增no-cache

    相关文章

      网友评论

        本文标题:Spring MVC 给response添加Cache-Cont

        本文链接:https://www.haomeiwen.com/subject/vspyihtx.html