CodeGym /Java Course /Module 5. Spring /Spring Boot and Web MVC, part 2

Spring Boot and Web MVC, part 2

Module 5. Spring
Level 16 , Lesson 1
Available

Static content

By default, Spring Boot processes static content from the /static directory (or /public or /resources, or /META-INF/resources) in the classpath or from the root ServletContext. The framework uses ResourceHttpRequestHandler from Spring MVC, so you can change this logic by adding your own WebMvcConfigurer and overriding the addResourceHandlers method.

In a standalone web application, the standard servlet from the container is not activated. It can be enabled using the server.servlet.register-default-servlet property.

The default servlet acts as a fallback, processing content from the root ServletContext , if Spring won't handle it. In most cases this does not happen (unless you change the default MVC configuration) because Spring is always able to handle requests via DispatcherServlet.

By default, resources are mapped to /**, but you can fine-tune this mapping through the spring.mvc.static-path-pattern property. For example, moving all resources to /resources/** can be done as follows:

Properties
spring.mvc.static-path-pattern=/resources/**
Yaml
spring:
    mvc:
        static-path-pattern: "/resources/**"

You can also customize the location of static resources with using the spring.web.resources.static-locations property (replacing the default values with a list of directory locations). The root path of the servlet context, "/", is automatically added as a location.

In addition to the "standard" static resource locations mentioned earlier, a special place is given to Webjars content. Any resources with a path in /webjars/** are processed from jar files if they are packaged in the Webjars format.

Do not use the src/main/webapp directory if the application is packaged as a jar file. Although this directory is a generally accepted standard, it works exclusively with war packaging, and it is silently ignored by most build tools if a jar file is generated.

Spring Boot also supports advanced functionality working with the resources provided by Spring MVC, allowing for scenarios such as disabling static resource caching or using version-independent URLs for Webjars.

To use version-independent Webjars URLs , add the webjars-locator-core dependency. Then declare your Webjar. Using jQuery as an example, adding "/webjars/jquery/jquery.min.js" results in "/webjars/jquery/x.y.z/jquery.min.js", where x.y.z – Webjar version.

If you are using JBoss, you need to declare a dependency webjars-locator-jboss-vfs instead of webjars-locator-core. Otherwise, all Webjars are resolved as 404.

To use the disable caching feature, the following configuration is configured to disable caching of all static resources by adding a hash of the content, such as <link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>, to URL:

Properties
spring.web.resources.chain.strategy.content.enabled=true
spring.web.resources.chain.strategy.content.paths=/**
Yaml
spring:
  web:
    resources:
      chain:
        strategy:
          content:
            enabled: true
            paths: "/**"
Resource links are rewritten in templates at runtime thanks to the ResourceUrlEncodingFilter, which automatically configures for Thymeleaf and FreeMarker. You must manually declare this filter when using JSP. Other templating engines are not currently supported automatically, but can be supported using custom templating macros/helper classes and using ResourceUrlProvider.

When loading resources dynamically, for example, using the JavaScript module loader, renaming files is not possible. Therefore, other strategies are supported and can be combined. The "fixed" strategy adds a static version string to the URL without changing the file name, as shown in the following example:

Properties
spring.web.resources.chain.strategy.content.enabled=true
spring.web.resources.chain.strategy.content.paths=/**
spring.web.resources.chain.strategy.fixed.enabled=true
spring.web.resources.chain.strategy.fixed.paths=/js/lib/
spring.web.resources.chain.strategy.fixed.version=v12
Yaml
spring:
  web:
    resources:
      chain:
        strategy:
          content:
            enabled: true
            paths: "/**"
          fixed:
            enabled: true
            paths: "/js/lib/"
            version: "v12"

With this configuration, JavaScript modules located in the "/js/lib/" directory, use a fixed versioning strategy ("/v12/js/lib/mymodule.js"), while other resources still use a content (<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>).

See WebProperties.Resources.

This function has been described in detail in a special blog post and in reference documentation Spring Framework.

Start Page

Spring Boot supports both static and template start pages. The framework first looks for the index.html file in the configured static content locations. If no such pattern is found, it looks for the index pattern. If one of them is found, it will automatically be used as the application's home page.

Custom Favicon

As with other static resources, Spring Boot checks for the presence of favicon.ico in configured static content locations. If such a file is present, it is automatically used as the web page icon (favicon) for the application.

Path mapping and content negotiation

Spring MVC can map incoming HTTP requests to handlers that by looking at the request path and matching it against mappings defined in the application (for example, @GetMapping annotations for controller methods).

Spring Boot disables suffix pattern matching by default, which means that requests like "GET /projects/spring-boot.json" will not be mapped to @GetMapping("/projects/spring-boot") mappings. This is considered the best practice for Spring MVC applications. In the past, this feature was primarily useful for HTTP clients that did not send proper "Accept" request headers; it was necessary to ensure that the correct content type was sent to the client. Content negotiation is now much more reliable.

There are other ways to deal with HTTP clients that do not always send the correct "Accept" request headers. Instead of using suffix matching, you can use a query parameter so that requests like "GET /projects/spring-boot?format=json" are guaranteed to match @GetMapping("/projects/spring-boot"):

Properties
spring.mvc.contentnegotiation.favor-parameter=true
Yaml
spring:
  mvc:
    contentnegotiation:
      favor-parameter: true

Or if you prefer to use a different parameter name:

Properties
spring.mvc.contentnegotiation.favor-parameter=true
spring.mvc.contentnegotiation.parameter-name=myparam
Yaml
spring:
  mvc:
    contentnegotiation:
      favor-parameter: true
      parameter-name: "myparam"

Most standard media types are supported out of the box, but you can also define new ones:

Properties
spring. mvc.contentnegotiation.media-types.markdown=text/markdown
Yaml
spring:
  mvc:
    contentnegotiation:
      media-types:
        markdown: "text/markdown"

Suffix pattern matching is deprecated and will be removed in the future release. If you understand the caveats and still want your application to use suffix pattern matching, you need to perform the following configuration:

Properties
spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-suffix-pattern=true
Yaml
spring:
  mvc:
    contentnegotiation:
      favor-path-extension: true
    pathmatch:
      use-suffix-pattern: true

Also, instead of opening all suffix patterns, a more reliable method would be to only support registered suffix patterns:

Properties
spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-registered-suffix-pattern=true
Yaml
spring:
  mvc:
    contentnegotiation:
      favor-path-extension: true
    pathmatch:
      use-registered-suffix-pattern: true

Starting with Spring Framework 5.3, Spring MVC supports several implementation strategies for mapping request paths to controller handlers. Previously it only supported the AntPathMatcher strategy, but now also offers PathPatternParser. Spring Boot now provides a configuration property that allows you to select and enable a new strategy:

Properties
spring.mvc.pathmatch.matching- strategy=path-pattern-parser
Yaml
spring:
  mvc:
    pathmatch:
      matching-strategy: "path-pattern-parser"

For more information on why you should pay attention to this new implementation, see dedicated blog post.

PathPatternParser is an optimized implementation, but limits the use of some variants of path patterns and is not compatible with suffix pattern matching (spring.mvc.pathmatch.use-suffix-pattern, spring.mvc.pathmatch.use-registered-suffix-pattern) or mapping DispatcherServlet with servlet prefix (spring.mvc.servlet.path).

ConfigurableWebBindingInitializer

Spring MVC uses WebBindingInitializer to initialize WebDataBinder for a specific request. If you create your own ConfigurableWebBindingInitializer marked with the @Bean annotation, Spring Boot will automatically configure Spring MVC to use it.

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION