Mastering Spring Boot Static Resources and Content Negotiation
This article explains how Spring Boot serves static resources from default locations, how to customize static path patterns and resource locations, handle Webjars, configure content negotiation with parameters and custom media types, and integrate template engines such as Thymeleaf, FreeMarker, and Mustache.
Environment: Spring Boot 2.4.12
Previous article: “What does Spring Boot do for Spring MVC? (Part 1)”.
Static Content
By default Spring Boot serves static content from class‑path directories named /static , /public , /resources or /META-INF/resources , or from the root of the ServletContext . It uses Spring MVC’s ResourceHttpRequestHandler , which can be customized by adding a WebMvcConfigurer and overriding addResourceHandlers .
In a standalone web application the container’s default servlet is also enabled as a fallback; if Spring does not handle a request, content is served from the ServletContext root. This rarely occurs unless the default MVC configuration is changed, because the DispatcherServlet normally processes all requests.
Static resources are mapped to /** by default. The pattern can be changed with the spring.mvc.static-path-pattern property, for example:
<code>spring:
mvc:
static-path-pattern: "/resources/**"
</code>The spring.web.resources.static-locations property can also be used to set the locations of static resources; the servlet root “/” is automatically added as a location.
Besides the standard locations, resources under /webjars/** are served from JAR files when packaged as WebJars.
Spring Boot also supports advanced resource handling features provided by Spring MVC, such as cache busting and version‑less URLs for WebJars.
To use version‑less URLs with WebJars, add the webjars‑locator‑core dependency and reference a WebJar, e.g. for jQuery:
Requesting “/Webjar/jQuery/jQuery.min.js” resolves to “/Webjar/jQuery/ x.y.z /jQuery.min.js”, where x.y.z is the WebJar version.
Welcome Page
Spring Boot supports static and template welcome pages. It first looks for an index.html file in the configured static locations; if none is found, it searches for an index template. The first match is used as the application’s welcome page.
Path Matching and Content Negotiation
Spring MVC maps incoming HTTP requests to handler methods by matching the request path with mappings defined on @GetMapping (or other mapping annotations) in controllers.
By default Spring Boot disables suffix pattern matching, so a request such as “GET /projects/spring-boot.json” does not match @GetMapping("/projects/spring-boot") . This follows best practices; modern clients should send proper Accept headers for content negotiation.
When clients cannot send correct Accept headers, a query parameter can be used to select a format, e.g. “GET /projects/spring-boot?format=json” maps to the same @GetMapping method.
Example:
<code>@GetMapping("/format")
public Map<String, Object> format() {
Map<String, Object> result = new HashMap<>();
result.put("name", "张三");
return result;
}
</code>The endpoint returns JSON when the request’s Accept header is application/json . If the client only accepts text/html , the request fails.
Configure content negotiation to favor a query parameter:
<code>spring:
mvc:
contentnegotiation:
favor-parameter: true
</code>Adding “?format=json” makes the request succeed. Changing the parameter value causes an error.
Customize the parameter name:
<code>spring:
mvc:
contentnegotiation:
favor-parameter: true
parameter-name: akf
</code>Now “?akf=json” works.
Define custom media types for request headers:
<code>spring:
mvc:
contentnegotiation:
media-types:
cnn: app/cnn
</code>Clients can now send Accept: app/cnn and receive the corresponding response.
ConfigurableWebBindingInitializer
Spring MVC uses a WebBindingInitializer to initialize a WebDataBinder for each request. Declaring a ConfigurableWebBindingInitializer bean causes Spring Boot to automatically configure Spring MVC to use it.
Template Engine
Beyond REST services, Spring MVC can render dynamic HTML using template engines such as Thymeleaf, FreeMarker, JSP, and many others.
Spring Boot provides auto‑configuration for the following template engines:
FreeMarker
Groovy
Thymeleaf
Mustache
If possible, avoid using JSP; there are known limitations when using it with embedded servlet containers.
Templates are automatically loaded from src/main/resources/templates when using the default configuration.
Finished!
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.