Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add Cache-Control header to static resource in Spring Boot?

How can I add Cache-Control HTTP header in Spring Boot for static resources?

Tried using a filter-component in the application, which writes headers correctly, but Cache-Control header gets overwritten.

@Component public class CacheBustingFilter implements Filter {      @Override     public void init(FilterConfig filterConfig) throws ServletException {     }      @Override     public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)                                                throws IOException, ServletException {          HttpServletResponse httpResp = (HttpServletResponse) resp;         httpResp.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");         httpResp.setHeader("This-Header-Is-Set", "no-cache, no-store, must-revalidate");         httpResp.setHeader("Expires", "0");          chain.doFilter(req, resp);     } 

What I get in the browser is:

Cache-Control:no-store This-Header-Is-Set:no-cache, no-store, must-revalidate Expires:0 

What I would like is:

Cache-Control:no-cache, no-store, must-revalidate This-Header-Is-Set:no-cache, no-store, must-revalidate Expires:0 
like image 654
MatteKarla Avatar asked Oct 19 '15 12:10

MatteKarla


People also ask

How do you set cache-control for static content?

Here is what you need to remember while caching static resources on CDN or local cache server: Use Cache-control HTTP directive to control who can cache the response, under which conditions, and for how long. Configure your server or application to send validation token Etag. Do not cache HTML in the browser.

How do I add a cache-control header?

If you want to enable Cache-Control for all files, add Header set line outside the filesMatch block. As you can see, we set the Cache-Control header's max-age to 3600 seconds and to public for the listed files.

Which header can potentially allow a resource to be loaded from cache?

Cache-control is an HTTP header used to specify browser caching policies in both client requests and server responses. Policies include how a resource is cached, where it's cached and its maximum age before expiring (i.e., time to live).


2 Answers

This happens because of Spring Security: it rewrites all cache headers to disable caching totally. So we need to do two things:

  1. Disable spring security for static resources
  2. Enable static resource cache processing

In current version of Spring Boot we can change this behavior in application.properties config.

Disable spring security for some resources:

# Comma-separated list of paths to exclude from the default secured  security.ignored=/myAssets/** 

Enable sending cache headers for static resources:

# Enable HTML5 application cache manifest rewriting. spring.resources.chain.html-application-cache=true  # Enable the Spring Resource Handling chain. Disabled by default unless at least one strategy has been enabled. spring.resources.chain.enabled=true # Enable the content Version Strategy. spring.resources.chain.strategy.content.enabled=true  # Comma-separated list of patterns to apply to the Version Strategy. spring.resources.chain.strategy.content.paths=/**   # Locations of static resources. spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ 

That's all. Now Spring will check if your static files was changed and can send smarter responses (If-Modiffied-Since and others) and rewrite your appcache also.

Also, if there are reasons to not use content-based version for some resources - you can use alternate FixedVersion strategy and set version explicitly in your config:

#Enable the fixed Version Strategy. spring.resources.chain.strategy.fixed.enabled=false  # Comma-separated list of patterns to apply to the Version Strategy. spring.resources.chain.strategy.fixed.paths=  # Version string to use for the Version Strategy. spring.resources.chain.strategy.fixed.version=  

See more in docs

like image 189
Alexandr Latushkin Avatar answered Sep 18 '22 09:09

Alexandr Latushkin


As per the documentation, of ResourceHandlerRegistry. It is pretty easy. (I have no code related to it right now.)

In the place where you configure your static resources just add addResourceHandler method, It will return ResourceHandlerRegistration object.

There you can use setCacheControl method. What you have to do is configure and set a CacheControl obejct.

This is since spring 4.2, else you will have to do it like below.

@Configuration @EnableWebMvc @ComponentScan("my.packages.here") public class WebConfig extends WebMvcConfigurerAdapter {      @Override     public void addResourceHandlers(ResourceHandlerRegistry registry) {         registry.addResourceHandler("/resources/**").setCachePeriod(0);     }  } 
like image 36
Maleen Abewardana Avatar answered Sep 22 '22 09:09

Maleen Abewardana