Refreshing Static Content with Spring MVC and Boot

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:

Sample Image

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



Leave a reply



Submit