Spring MVC에서 캐시 헤더를 어떻게 설정합니까?
Spring MVC에서 캐시 헤더를 어떻게 설정합니까?
주석 기반 Spring MVC 컨트롤러에서 특정 경로에 대한 캐시 헤더를 설정하는 선호되는 방법은 무엇입니까?
모든 Spring 컨트롤러의 기본 클래스 인 org.springframework.web.servlet.support.WebContentGenerator 에는 캐시 헤더를 처리하는 몇 가지 메소드가 있습니다.
/* Set whether to use the HTTP 1.1 cache-control header. Default is "true".
* <p>Note: Cache headers will only get applied if caching is enabled
* (or explicitly prevented) for the current request. */
public final void setUseCacheControlHeader();
/* Return whether the HTTP 1.1 cache-control header is used. */
public final boolean isUseCacheControlHeader();
/* Set whether to use the HTTP 1.1 cache-control header value "no-store"
* when preventing caching. Default is "true". */
public final void setUseCacheControlNoStore(boolean useCacheControlNoStore);
/* Cache content for the given number of seconds. Default is -1,
* indicating no generation of cache-related headers.
* Only if this is set to 0 (no cache) or a positive value (cache for
* this many seconds) will this class generate cache headers.
* The headers can be overwritten by subclasses, before content is generated. */
public final void setCacheSeconds(int seconds);
콘텐츠 생성 전에 컨트롤러 내에서 호출하거나 Spring 컨텍스트에서 빈 속성으로 지정할 수 있습니다.
방금 동일한 문제가 발생했고 프레임 워크에서 이미 제공 한 좋은 솔루션을 찾았습니다. 이 org.springframework.web.servlet.mvc.WebContentInterceptor
클래스를 사용하면 기본 캐싱 동작과 경로 별 재정의 (다른 곳에서 사용되는 것과 동일한 경로 일치 동작 사용)를 정의 할 수 있습니다. 나를위한 단계는 다음과 같습니다.
- 내 인스턴스에
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
"cacheSeconds"속성이 설정되어 있지 않은지 확인 합니다. 의 인스턴스 추가
WebContentInterceptor
:<mvc:interceptors> ... <bean class="org.springframework.web.servlet.mvc.WebContentInterceptor" p:cacheSeconds="0" p:alwaysUseFullPath="true" > <property name="cacheMappings"> <props> <!-- cache for one month --> <prop key="/cache/me/**">2592000</prop> <!-- don't set cache headers --> <prop key="/cache/agnostic/**">-1</prop> </props> </property> </bean> ... </mvc:interceptors>
이러한 변경 후 / foo 아래의 응답에는 캐싱을 막기 위해 헤더가 포함되었고, / cache / me 아래의 응답에는 캐싱을 장려하는 헤더가 포함되었으며, / cache / agnostic 아래의 응답에는 캐시 관련 헤더가 포함되지 않았습니다.
순수 Java 구성을 사용하는 경우 :
@EnableWebMvc
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
/* Time, in seconds, to have the browser cache static resources (one week). */
private static final int BROWSER_CACHE_CONTROL = 604800;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/images/**")
.addResourceLocations("/images/")
.setCachePeriod(BROWSER_CACHE_CONTROL);
}
}
참조 : http://docs.spring.io/spring-security/site/docs/current/reference/html/headers.html
대답은 아주 간단합니다.
@Controller
public class EmployeeController {
@RequestMapping(value = "/find/employer/{employerId}", method = RequestMethod.GET)
public List getEmployees(@PathVariable("employerId") Long employerId, final HttpServletResponse response) {
response.setHeader("Cache-Control", "no-cache");
return employeeService.findEmployeesForEmployer(employerId);
}
}
위의 코드는 달성하려는 것을 정확하게 보여줍니다. 두 가지를해야합니다. "최종 HttpServletResponse 응답"을 매개 변수로 추가하십시오. 그런 다음 헤더 Cache-Control을 no-cache로 설정하십시오.
Spring 4.2 부터 다음과 같이 할 수 있습니다.
import org.springframework.http.CacheControl;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
@RestController
public class CachingController {
@RequestMapping(method = RequestMethod.GET, path = "/cachedapi")
public ResponseEntity<MyDto> getPermissions() {
MyDto body = new MyDto();
return ResponseEntity.ok()
.cacheControl(CacheControl.maxAge(20, TimeUnit.SECONDS))
.body(body);
}
}
CacheControl
object는 많은 구성 옵션이있는 빌더입니다. JavaDoc을 참조하십시오.
You could use a Handler Interceptor and use the postHandle method provided by it:
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
then just add a header as follows in the method:
response.setHeader("Cache-Control", "no-cache");
you can define a anotation for this: @CacheControl(isPublic = true, maxAge = 300, sMaxAge = 300)
, then render this anotation to HTTP Header with Spring MVC interceptor. or do it dynamic:
int age = calculateLeftTiming();
String cacheControlValue = CacheControlHeader.newBuilder()
.setCacheType(CacheType.PUBLIC)
.setMaxAge(age)
.setsMaxAge(age).build().stringValue();
if (StringUtils.isNotBlank(cacheControlValue)) {
response.addHeader("Cache-Control", cacheControlValue);
}
Implication can be found here: 优雅的Builder模式
BTW: I just found that Spring MVC has build-in support for cache control: Google WebContentInterceptor or CacheControlHandlerInterceptor or CacheControl, you will find it.
I know this is a really old one, but those who are googling, this might help:
@Override
protected void addInterceptors(InterceptorRegistry registry) {
WebContentInterceptor interceptor = new WebContentInterceptor();
Properties mappings = new Properties();
mappings.put("/", "2592000");
mappings.put("/admin", "-1");
interceptor.setCacheMappings(mappings);
registry.addInterceptor(interceptor);
}
In your controller, you can set response headers directly.
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
You could extend AnnotationMethodHandlerAdapter to look for a custom cache control annotation and set the http headers accordingly.
I found WebContentInterceptor
to be the easiest way to go.
@Override
public void addInterceptors(InterceptorRegistry registry)
{
WebContentInterceptor interceptor = new WebContentInterceptor();
interceptor.addCacheMapping(CacheControl.noCache(), "/users", "admin");
registry.addInterceptor(interceptor);
}
참고URL : https://stackoverflow.com/questions/1362930/how-do-you-set-cache-headers-in-spring-mvc