Problem I'd like to include Cache-Control headers only on certain static files, by solely using the application.yml file and the properties as set here > https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html .
- I want to set the Cache-Control max-age to a year for all CSS, JS and WOFF2 files in the /static/ folder
- I do not want set any Cache-Control header on the index.html file in the /static/ folder
- I only want to touch the application.yml file in order to accomplish this. I know I can override these settings in Java files, but I'd really like to separate this logic and only use application.yml for all things compression, cache and http2 related.
Solution
- Just as you did with https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#application-properties.server, include a mime-types property for spring.web.resources.cache.cachecontrol.
- We'll have to disable Spring Security completely if we want to override cache-control headers. Surely there must be a better way to still leave on Spring Security and set cache-control headers for static files inside application.yml?
I look forward to your response. Thanks in advance!
Comment From: wilkinsona
Thanks for the suggestion. Can you share a bit more information about the properties that you'd like to be added? Right now, I'm struggling to see how we could offer property-based cache-control configuration on a per-mime-type basis. The equivalent code that you can use to achieve the same goal would also be useful in helping me to understand what you're looking for.
Comment From: martijn19811
Hi,
sorry for the late reply. I was thinking something along the lines of this:
spring:
web:
resources:
cache:
types:
- mime-types: text/html
max-age: 0
- mime-types: application/javascript, text/css, text/plain
max-age: 1y
- mime-types: application/font-woff2
max-age: 1M
The above should be the equivalent of an array with objects, YAML-style though.
Comment From: bclozel
Do you already achieve that with Java configuration? Do you have a specific Resource handler implementation for that?
Looking at the current ˋResourceHandlerRegistration` in Spring Framework, it looks like the caching configuration is only location based, not based on mime types.
I suspect that you can achieve your goal by configuring yourself the resource registrations (using specific locations for types) - but I don't think that the current Spring Framework infrastructure allows this.
Can you look into this and let us know?
Comment From: martijn19811
Hi,
I'd like to refer to the 3rd bullet point in the first list in my original starter post. I thoroughly believe that it makes for a much cleaner architecture to move all the server-related logic (http2, compression and caching) outside of the Java application. This way, it would also be possible for other applications inside companies to inherit the same configuration (if all use the same base application.yml), therefore centralizing these optimizations.
Comment From: martijn19811
So, what I mean to say is: yes, it is possible to inside my Java application to set cache-control headers, but I do think on a grander scale that this is not the way to go. The current setup only provides hybrid solutions and I think it would be a much better idea to separate these concerns.
Comment From: bclozel
I understand your 3rd point - what I meant is: I'm not sure we can achieve that with the current Spring MVC infrastructure. Spring Boot can offer new configuration properties, but with some limitations:
- the underlying infrastructure must allow it
- we want to keep things simple and avoid a general "programming by properties" intent
Right now, I don't think 1) is possible with Spring Framework - if you ever managed to get something like this working in your application, it would be useful to share some code so that we can learn more about the use case. This part of the Spring Framework reference docs should help.
I'm wondering if the main problem here is the fact that you're hosting static HTML files (that are meant to change often with your app) and static resources (with a more agressive HTTP caching strategy) in the same location. You could configure a separate location as classpath:static-html/
and serve all HTML files from there. JS and CSS files are often built with a different pipeline and they can be suffixed for better caching strategies (see this sample repository for examples).
Comment From: martijn19811
Thanks, that is what I was looking for exactly! Thanks for alle the background information as well. You may close this issue.
Comment From: bclozel
I'm glad we've found a way to have that feature implemented in your application! If you need more help, don't hesitate to create a StackOverflow question showing what you've tried and link back to it from this issue so that I can have a look.