Refreshing static content with Spring MVC and Boot
The docs say "all modern IDEs allow reloading of static resources and usually also hot-swapping of Java class changes" (https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/html/howto.html#howto-hotswapping). It's true. Eclipse does it more or less by default, and I'm not an IntelliJ user, but from what I understand you can configure it to build automatically as well.
Can static content on spring-boot-web application be dynamic (refreshed)?
The problem is to download the file with the dynamic content from a Spring app.
This can be solved with Spring BOOT. Here is the solution as shown in this illustration - when i click Download report, my app generates a dynamic Excel report and its downloaded to the browser:
From a JS, make a get request to a Spring Controller:
function DownloadReport(e){
//Post the values to the controller
window.location="../report" ;
}
Here is the Spring Controller GET Method with /report:
@RequestMapping(value = ["/report"], method = [RequestMethod.GET])
@ResponseBody
fun report(request: HttpServletRequest, response: HttpServletResponse) {
// Call exportExcel to generate an EXCEL doc with data using jxl.Workbook
val excelData = excel.exportExcel(myList)
try {
// Download the report.
val reportName = "ExcelReport.xls"
response.contentType = "application/vnd.ms-excel"
response.setHeader("Content-disposition", "attachment; filename=$reportName")
org.apache.commons.io.IOUtils.copy(excelData, response.outputStream)
response.flushBuffer()
} catch (e: Exception) {
e.printStackTrace()
}
}
This code is implemented in Kotlin - but you can implement it as easily in Java too.
Spring MVC application and static content updating
The static resources were created to optimize the time these resources are served. And the optimization is made at build time, so it can't no reload automatically by definition.
https://spring.io/blog/2014/07/24/spring-framework-4-1-handling-static-web-resources
Spring Boot triggers full restart instead of reload on changes over static files
Finally found the solution. It was much simpler than I thought.
Since I'm using war packaging I can use webapp's default behaviour. Everything under source folders trigger a restart, but resources under webapp are fetched at runtime, so there is no need to reload anything.
I just placed my static content under /webapp/static and then added the resource handler:
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
}
Just don't use the default Spring Boot placement for statics (basically anything under resources) and you'll be fine.
how to serve static content in springboot 2.2.6?
Starting with a simple spring boot initializer
... we can place static (html) files into one of:
- (src/main/resources:)
- static
- resources
- public
- META-INF
- resources
which results in the default (class path) locations, configured via the spring.resources.static-locations
property.
These will be exposed through the value of spring.mvc.static-path-pattern
-property (ref), by default: /**
.
So a static index.html file in one of the above mentioned folders, with default config, will be accessible at:
- http:localhost:8080/ (due to "welcome file mapping" -> static mapping)
- and http://localhost:8080/index.html (due to the static mapping)
Accordingly: no problem with http://localhost:8080/test.html ...
Checkout at github.
So this, at least answers the "question title" "how to serve static content in springboot 2.2.6?".
The order of spring.resources.static-locations
appears (index.html preferred from META-INF/resources) also to be the "precedence" of static file locations (left-to-right, first match wins).
When we add @EnableWebMvc
..."evertyhing gets broken" (context loads, but) only:
WARN ... o.s.web.servlet.PageNotFound : No mapping for GET /
WARN ... o.s.web.servlet.PageNotFound : No mapping for GET /index.html
WARN ... o.s.web.servlet.PageNotFound : No mapping for GET /test.html
..please aslo consider this: why spring-boot application doesn't require @EnableWebMvc
With "non-default config", You would have to provide more details, to find a specific solution.
But for "newbie in Springboot": starting with an intializer and "the defaults" sounds optimal! From here on, you can re-fine your configuration based on a working one.
And if you want/need the @EnableWebMvc
annotation for some reason, this will result in the "previous" behavior again/restore the (2.2.6) default static content handling:
@EnableWebMvc
@SpringBootApplication
public class DemoApplication implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/**")
.addResourceLocations("classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/");
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
(Assuming no conflicts with existing configuration/resource handlers)
Related Topics
How to Serialize Object to CSV File
Simplest Way to Print an 'Intstream' as a 'String'
Java 8 Lambda Expression and First-Class Values
How to Send Data to Com Port Using Java
When and How Are Classes Garbage Collected in Java
Found Shared References to a Collection Org.Hibernate.Hibernateexception
How to Get Java to Ignore the "Trust Store" and Just Accept Whatever Ssl Certificate It Gets
Java: Subtract '0' from Char to Get an Int... Why Does This Work
What Is Mutex and Semaphore in Java? What Is the Main Difference
Access to File Using Java with Samba Jcifs
Spring - Injecting a Dependency into a Servletcontextlistener
Is There Any Good and Free Date and Time Picker Available for Java Swing
Javafx and Maven: Nullpointerexception: Location Is Required
How to Properly Do a Background Thread When Using Spring Data and Hibernate
Create Java Runtime Image on One Platform for Another Using Jlink