Как установить заголовки кэша в Spring MVC?
в контроллере Spring MVC на основе аннотаций, каков предпочтительный способ установки заголовков кэша для определенного пути?
10 ответов:
орг.springframework.сеть.сервлет.поддержка.WebContentGenerator, который является базовым классом для всех контроллеров Spring имеет довольно много методов, связанных с заголовками кэша:
/* 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 включены заголовки, чтобы препятствовать кэширования, ответы под /кэш/меня в том числе заголовки, чтобы стимулировать кэширование, и ответы под /кэш/агностик не связанные с кэшем заголовки.
при использовании чистой конфигурации 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
ответ довольно прост:
Код выше показывает именно то, что вы хотите достичь. Вы должны сделать две вещи. Добавьте в качестве параметра" final HttpServletResponse response". А затем установите заголовок Cache-Control в no-cache.@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); }
}
начиная с Весна 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
объект-это конструктор со многими параметрами конфигурации, см. документация
Вы можете использовать перехватчик обработчика и использовать метод postHandle, предоставленный им:
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
тогда просто добавьте заголовок следующим образом в методе:
response.setHeader("Cache-Control", "no-cache");
вы можете определить анотацию для этого:
@CacheControl(isPublic = true, maxAge = 300, sMaxAge = 300)
, затем визуализируйте эту анотацию в HTTP-заголовок с помощью перехватчика Spring MVC. или сделать это динамично: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); }
подтекст можно найти здесь: 优雅的Builder模式
кстати: я только что обнаружил, что Spring MVC имеет встроенную поддержку для управления кешем: Google WebContentInterceptor или CacheControlHandlerInterceptor или CacheControl, вы найдете его.
Я знаю, что это действительно старый, но те, кто гуглит, это может помочь:
@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); }
вы можете расширить AnnotationMethodHandlerAdapter, чтобы найти пользовательскую аннотацию управления кэшем и соответственно установить заголовки http.