Spring: Disable caching of template and static files - spring

While using Spring Boot v2.6.3, Spring v5.3.15 and Java 17.0.2,
I put the devtools dependency in pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
In application.yml, I have this:
spring:
thymeleaf:
cache: false
cache:
type: none
devtools:
restart:
enabled: true
If I do a change (java, template or static css file), I have to rebuild the project for the new content to appear in the browser.
Is there a way to prevent Spring from caching the templates and the static files?

When it comes to spring-boot, by default the template options such as Thymeleaf and FreeMarker are configured to be cached. It is done in that way because the template parsing don’t need to be reparsed with every request they serve. Even that is useful in production cached templates are not so great at development time. Cached templates will still be in use until you restart the application.
DevTools addresses this issue by automatically disabling all template caching. However as you explained it didn't work for you. Therefore I suggest you remove using DevTools and use the below mentioned application property.
To disable the caching all you need to do is set a template-appropriate caching property to false. I will mention different properties for different templates for disable the caching.
FreeMarker spring.freemarker.cache
Groovy Templates spring.groovy.template.cache
Mustache spring.mustache.cache
Thymeleaf spring.thymeleaf.cache
By default, all of these properties are set to true to enable caching. You can disable caching for your chosen template engine by setting its cache property to false.
For testing purpose, just remove the spring configuration you mentioned in your question and just add the following.
spring:
thymeleaf:
cache: false
This works for me and if this doesn't work for you then if should be a different problem.

Related

Spring Cloud Embedded Config Server with native repository

I have a working spring boot application and I am trying to remove some properties from application.yaml file and read them from an embedded config server in the same app. At the moment, I am trying to read properties from file system through "native" profile type, and I am planning to later replace this with S3. Also, I am trying to read the configuration directly from backend repository as explained here https://docs.spring.io/spring-cloud-config/docs/current/reference/html/#_embedding_the_config_server , rather than connecting through an endpoint.
If you want to read the configuration for an application directly from
the backend repository (instead of from the config server), you
basically want an embedded config server with no endpoints. You can
switch off the endpoints entirely by not using the #EnableConfigServer
annotation (set spring.cloud.config.server.bootstrap=true).
I have introduced following changes to my existing application to achieve this.
Added following dependencies to pom.xml
spring-cloud-starter-config
spring-cloud-config-server
spring-cloud-config-client
application-dev.yaml
spring:
could:
bootstrap:
enabled: true
bootstrap.yaml
spring:
profiles:
active: composite
cloud:
config:
server:
composite:
- type: native
search-locations: file:C:\\Users\\chamila\\config-test\\config
# bootstrap: true
The required properties are saved in a different application-dev.yaml file at the above file path. I have not used #EnableConfigServer annotation from my app class, as I want connect directly without the endpoint.
However, still my program is failing to read the properties from the config-server. I tried setting spring.cloud.config.server.bootstrap=true and spring.cloud.bootstrap.enabled=true from both application-dev.yaml and bootstrap.yaml, but it didn't work?
Any idea what I am missing? I note that I never specified how to connect to the config-server in my application-dev.yaml file also. Is that an issue?
Any help is highly appreciated.
I created a sample project of an embedded Configuration Server which uses a custom repository:
https://github.com/taxone/embedded-config-server
The initial problem was that the custom EnvironmentRepository was not available via bootstrap, as described in this issue.
I followed https://cloud.spring.io/spring-cloud-config/reference/html/#_embedding_the_config_server and achieved the expected result.
Add spring-cloud-starter-bootstrap to your dependencies as suggested in https://github.com/taxone/embedded-config-server.
Make sure that composite profile is active when you start the app.
Verify that your native configuration is added by finding a log message from NativeEnvironmentRepository during startup.
(Optional) Remove spring.cloud.bootstrap.enabled from application-dev.yaml.
(Optional) Remove spring-cloud-config-client dependency as it is included in both spring-cloud-starter-config and
spring-cloud-config-server.
(Further steps) Use #RefreshScope on a spring bean to achieve dynamic properties. Requires POST actuator/refresh.

Integration tests in spring boot application with spring cloud

I have an spring-boot application that uses config server.
In project I have a bootstrap.yml:
spring:
cloud:
config:
uri: ${CLOUD_CONFIG_URI:http://localhost:8888}
failFast: true
enabled: ??
and I can pass actual config for server location through parameter. That's ok.
With this configuration I don't know how to disable this in integration tests. My tests load this configuration and want to communicate with config server. I know that I can pass spring.cloud.config.enabled=false but it's not a solution (I want to right click in IDE and run test without additional configuration per each test method).
Any idea?
This is a late answer but for the people that join from any search engines here is my solution:
The #Profile("test") annotation above your integration test class is correct. To get this really working is adding two extra configuration files to your normal resources folder, not the test resources folder.
Add "application-test.yml"
Add "bootstrap-test.yml"
In your bootstrap-test.yml add the following:
spring:
cloud:
config:
enabled: false
With this configuration you can put all of your needed configuration options in the application-test.yml and the bootstrap-test.yml will disabled spring cloud config.

Reload static content spring boot application

I am using Netbeans and I am developing my first web application using spring boot. I was keeping my HTML, js, CSS in "webapp" folder and then I refactored my project and I put all static content in /resources/static. Since then, I have to rebuild my project every time because the static content isn't reloaded.
Can I easily bypass this problem if I'll use browser-sync plugin for Gulp?
Add the following to src/main/resources/application.properties:
spring.web.resources.static-locations[0]=file:src/main/resources/static/
spring.web.resources.static-locations[1]=classpath:/static/
The "file:" causes the content to be reloaded on refreshing the browser,
see related issue.
Alternatively, the file resource locations can be discovered at runtime and added programmatically.
See also documentation and tutorial.
Note that prior to Spring Boot 2.4, the property was called "spring.resources.static-locations".
Normally the static content is copied to the build directory ( target if you are using maven) by the spring-boot plugin. You can find your files at {build-directory}/classes/static: These are the files that you should modify to reflect changes. You should also copy your changes to resources/static, because whenever you restart spring boot, the files are copied.
if an application.yml file is used for configuration, insert:
spring:
web:
resources:
static-locations[0]: "file:src/main/resources/static/"
static-locations[1]: "classpath:/static/"

Spring Boot Freemarker - html escaping by default

Is there any convenient way to enable html escaping by default for all freemarker templates when using spring boot autoconfiguration?
If not, what's proper way to add any of following solutions (keeping spring boot autoconfiguration defaults except of template loader)?
Default escaping in Freemarker
http://watchitlater.com/blog/2011/10/default-html-escape-using-freemarker/
After following ddekany's advice to use 2.3.24 here's solution:
Modify all template names to .ftlh (required by freemarker to automatically turn on HTML escaper) - including spring.ftl if it's being used. Updated spring.ftlh migh need some '?no_esc' additions for attributes
Adjust freemarker config to use those files:
spring.freemarker.suffix=.ftlh
spring.freemarker.settings.recognize_standard_file_extensions=true
Modify pom.xml to use freemarker 2.3.24:
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>freemarker-2.3.24-pre01</version>
</dependency>
Following solution is to use local JAR file because 2.3.24 is not yet on maven:
mvn install:install-file -Dfile="freemarker-2.3.24-pre01.jar" -DgroupId="org.freemarker" -DartifactId="freemarker" -Dversion="freemarker-2.3.24-pre01" -Dpackaging=jar
Voila, automatic freemarker HTML escaping for Spring Boot ;)
FreeMarker 2.3.24 has auto-escaping as core feature, though when I write this it's not yet released. Until that (1-2 mongth I guess), 2.3.24-pre01 is downloadable from the homepage, or you can build the 2.3-gae branch head (though not much has changed if you are only using auto-escaping among the 2.3.24 features). Auto-escaping is currently described there: http://freemarker.incubator.apache.org/builds/2.3.24-pre01/_html/dgui_misc_autoescaping.html
If you can't use 2.3.24 in this form, as the first post you have linked describes, you can use a custom TemplateLoader. As templateLoader (template_loader) is just a FreeMarker configuration setting, hopefully it can be set in Spring too.

Clear swagger Cache for Jersey project

I have created Java RESTFUL web serivces using Jersey, I am using swagger for API documentation. however swagger annotation changes during development for my RESTFUL services are not visible, I have tried clearing browser cache and used other browsers as well, but new changes does not reflect on Swagger API documentation. Swagger core dependencies are located in shared libraries directory.
Wokaround
In order for the changes to take effect I have to delete the following folders in Glass-fish.
generated
osgi-cache
and then redeploy the application (this require complete shutdown of the Glass fish server, otherwise system does not allow me to delete above folders.)
My Questions:
1 - Is there any way we can permanently disabled the caching?
2 - Is there any method to clear swagger cache on demand without restarting or deleting the folders?
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-jaxrs_2.10</artifactId>
<version>1.3.10</version>
</dependency>
Following the comments above, the solution is to use com.wordnik.swagger.jaxrs.listing.ApiListingCache.invalidateCache() during the start up of the application.
It should be noted that for some version of swagger-core, some parts are static and as such, using it as a shared lib will override the definitions for all the applications that use it on the same application server. The better solution would be to include the swagger-core dependency in each application separately.

Resources