Backend Development 8 min read

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.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Mastering Spring Boot Static Resources and Content Negotiation

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 BootTemplate EngineStatic ResourcesContent NegotiationWebjars
Spring Full-Stack Practical Cases
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.