Java

Spring MVC 给response添加Cache-Cont

2020-04-26  本文已影响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");
    }
}

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
上一篇下一篇

猜你喜欢

热点阅读