[[howto.spring-mvc]]
= Spring MVC

Spring Boot has a number of starters that include Spring MVC.
Note that some starters include a dependency on Spring MVC rather than include it directly.
This section answers common questions about Spring MVC and Spring Boot.



[[howto.spring-mvc.write-json-rest-service]]
== Write a JSON REST Service

Any Spring javadoc:org.springframework.web.bind.annotation.RestController[format=annotation] in a Spring Boot application should render JSON response by default as long as Jackson2 is on the classpath, as shown in the following example:

include-code::MyController[]

As long as `MyThing` can be serialized by Jackson2 (true for a normal POJO or Groovy object), then `http://localhost:8080/thing` serves a JSON representation of it by default.
Note that, in a browser, you might sometimes see XML responses, because browsers tend to send accept headers that prefer XML.



[[howto.spring-mvc.write-xml-rest-service]]
== Write an XML REST Service

If you have the Jackson XML extension (`jackson-dataformat-xml`) on the classpath, you can use it to render XML responses.
The previous example that we used for JSON would work.
To use the Jackson XML renderer, add the following dependency to your project:

[source,xml]
----
<dependency>
	<groupId>com.fasterxml.jackson.dataformat</groupId>
	<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
----

If Jackson's XML extension is not available and JAXB is available, XML can be rendered with the additional requirement of having `MyThing` annotated as javadoc:jakarta.xml.bind.annotation.XmlRootElement[format=annotation], as shown in the following example:

include-code::MyThing[]

You will need to ensure that the JAXB library is part of your project, for example by adding:

[source,xml]
----
<dependency>
	<groupId>org.glassfish.jaxb</groupId>
	<artifactId>jaxb-runtime</artifactId>
</dependency>
----

NOTE: To get the server to render XML instead of JSON, you might have to send an `Accept: text/xml` header (or use a browser).



[[howto.spring-mvc.customize-jackson-objectmapper]]
== Customize the Jackson ObjectMapper

Spring MVC (client and server side) uses javadoc:org.springframework.boot.autoconfigure.http.HttpMessageConverters[] to negotiate content conversion in an HTTP exchange.
If Jackson is on the classpath, you already get the default converter(s) provided by javadoc:org.springframework.http.converter.json.Jackson2ObjectMapperBuilder[], an instance of which is auto-configured for you.

The javadoc:com.fasterxml.jackson.databind.ObjectMapper[] (or javadoc:com.fasterxml.jackson.dataformat.xml.XmlMapper[] for Jackson XML converter) instance (created by default) has the following customized properties:

* `MapperFeature.DEFAULT_VIEW_INCLUSION` is disabled
* `DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES` is disabled
* `SerializationFeature.WRITE_DATES_AS_TIMESTAMPS` is disabled
* `SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS` is disabled

Spring Boot also has some features to make it easier to customize this behavior.

You can configure the javadoc:com.fasterxml.jackson.databind.ObjectMapper[] and javadoc:com.fasterxml.jackson.dataformat.xml.XmlMapper[] instances by using the environment.
Jackson provides an extensive suite of on/off features that can be used to configure various aspects of its processing.
These features are described in several enums (in Jackson) that map onto properties in the environment:

|===
| Enum | Property | Values

| javadoc:com.fasterxml.jackson.databind.cfg.EnumFeature[]
| `spring.jackson.datatype.enum.<feature_name>`
| `true`, `false`

| javadoc:com.fasterxml.jackson.databind.cfg.JsonNodeFeature[]
| `spring.jackson.datatype.json-node.<feature_name>`
| `true`, `false`

| javadoc:com.fasterxml.jackson.databind.DeserializationFeature[]
| `spring.jackson.deserialization.<feature_name>`
| `true`, `false`

| javadoc:com.fasterxml.jackson.core.JsonGenerator$Feature[]
| `spring.jackson.generator.<feature_name>`
| `true`, `false`

| javadoc:com.fasterxml.jackson.databind.MapperFeature[]
| `spring.jackson.mapper.<feature_name>`
| `true`, `false`

| javadoc:com.fasterxml.jackson.core.JsonParser$Feature[]
| `spring.jackson.parser.<feature_name>`
| `true`, `false`

| javadoc:com.fasterxml.jackson.databind.SerializationFeature[]
| `spring.jackson.serialization.<feature_name>`
| `true`, `false`

| javadoc:com.fasterxml.jackson.annotation.JsonInclude$Include[]
| configprop:spring.jackson.default-property-inclusion[]
| `always`, `non_null`, `non_absent`, `non_default`, `non_empty`
|===

For example, to enable pretty print, set `spring.jackson.serialization.indent_output=true`.
Note that, thanks to the use of xref:reference:features/external-config.adoc#features.external-config.typesafe-configuration-properties.relaxed-binding[relaxed binding], the case of `indent_output` does not have to match the case of the corresponding enum constant, which is `INDENT_OUTPUT`.

This environment-based configuration is applied to the auto-configured javadoc:org.springframework.http.converter.json.Jackson2ObjectMapperBuilder[] bean and applies to any mappers created by using the builder, including the auto-configured javadoc:com.fasterxml.jackson.databind.ObjectMapper[] bean.

The context's javadoc:org.springframework.http.converter.json.Jackson2ObjectMapperBuilder[] can be customized by one or more javadoc:org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer[] beans.
Such customizer beans can be ordered (Boot's own customizer has an order of 0), letting additional customization be applied both before and after Boot's customization.

Any beans of type javadoc:com.fasterxml.jackson.databind.Module[] are automatically registered with the auto-configured javadoc:org.springframework.http.converter.json.Jackson2ObjectMapperBuilder[] and are applied to any javadoc:com.fasterxml.jackson.databind.ObjectMapper[] instances that it creates.
This provides a global mechanism for contributing custom modules when you add new features to your application.

NOTE: If you wish to register additional modules programmatically using a javadoc:org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer[], make sure to use the `modulesToInstall` method that takes a consumer as the other variants are not additive.

If you want to replace the default javadoc:com.fasterxml.jackson.databind.ObjectMapper[] completely, either define a javadoc:org.springframework.context.annotation.Bean[format=annotation] of that type or, if you prefer the builder-based approach, define a javadoc:org.springframework.http.converter.json.Jackson2ObjectMapperBuilder[] javadoc:org.springframework.context.annotation.Bean[format=annotation].
When defining an javadoc:com.fasterxml.jackson.databind.ObjectMapper[] bean, marking it as javadoc:org.springframework.context.annotation.Primary[format=annotation] is recommended as the auto-configuration's javadoc:com.fasterxml.jackson.databind.ObjectMapper[] that it will replace is javadoc:org.springframework.context.annotation.Primary[format=annotation].
Note that, in either case, doing so disables all auto-configuration of the javadoc:com.fasterxml.jackson.databind.ObjectMapper[].

If you provide any javadoc:org.springframework.context.annotation.Bean[format=annotation]s of type javadoc:org.springframework.http.converter.json.MappingJackson2HttpMessageConverter[], they replace the default value in the MVC configuration.
Also, a convenience bean of type javadoc:org.springframework.boot.autoconfigure.http.HttpMessageConverters[] is provided (and is always available if you use the default MVC configuration).
It has some useful methods to access the default and user-enhanced message converters.

See the xref:spring-mvc.adoc#howto.spring-mvc.customize-responsebody-rendering[] section and the {code-spring-boot-autoconfigure-src}/web/servlet/WebMvcAutoConfiguration.java[`WebMvcAutoConfiguration`] source code for more details.



[[howto.spring-mvc.customize-responsebody-rendering]]
== Customize the @ResponseBody Rendering

Spring uses javadoc:org.springframework.boot.autoconfigure.http.HttpMessageConverters[] to render javadoc:org.springframework.web.bind.annotation.ResponseBody[format=annotation] (or responses from javadoc:org.springframework.web.bind.annotation.RestController[format=annotation]).
You can contribute additional converters by adding beans of the appropriate type in a Spring Boot context.
If a bean you add is of a type that would have been included by default anyway (such as javadoc:org.springframework.http.converter.json.MappingJackson2HttpMessageConverter[] for JSON conversions), it replaces the default value.
A convenience bean of type javadoc:org.springframework.boot.autoconfigure.http.HttpMessageConverters[] is provided and is always available if you use the default MVC configuration.
It has some useful methods to access the default and user-enhanced message converters (For example, it can be useful if you want to manually inject them into a custom javadoc:org.springframework.web.client.RestTemplate[]).

As in normal MVC usage, any javadoc:org.springframework.web.servlet.config.annotation.WebMvcConfigurer[] beans that you provide can also contribute converters by overriding the `configureMessageConverters` method.
However, unlike with normal MVC, you can supply only additional converters that you need (because Spring Boot uses the same mechanism to contribute its defaults).
Finally, if you opt out of the default Spring Boot MVC configuration by providing your own javadoc:org.springframework.web.servlet.config.annotation.EnableWebMvc[format=annotation] configuration, you can take control completely and do everything manually by using `getMessageConverters` from javadoc:org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport[].

See the {code-spring-boot-autoconfigure-src}/web/servlet/WebMvcAutoConfiguration.java[`WebMvcAutoConfiguration`] source code for more details.



[[howto.spring-mvc.multipart-file-uploads]]
== Handling Multipart File Uploads

Spring Boot embraces the servlet 5 javadoc:jakarta.servlet.http.Part[] API to support uploading files.
By default, Spring Boot configures Spring MVC with a maximum size of 1MB per file and a maximum of 10MB of file data in a single request.
You may override these values, the location to which intermediate data is stored (for example, to the `/tmp` directory), and the threshold past which data is flushed to disk by using the properties exposed in the javadoc:org.springframework.boot.autoconfigure.web.servlet.MultipartProperties[] class.
For example, if you want to specify that files be unlimited, set the configprop:spring.servlet.multipart.max-file-size[] property to `-1`.

The multipart support is helpful when you want to receive multipart encoded file data as a javadoc:org.springframework.web.bind.annotation.RequestParam[format=annotation]-annotated parameter of type javadoc:org.springframework.web.multipart.MultipartFile[] in a Spring MVC controller handler method.

See the {code-spring-boot-autoconfigure-src}/web/servlet/MultipartAutoConfiguration.java[`MultipartAutoConfiguration`] source for more details.

NOTE: It is recommended to use the container's built-in support for multipart uploads rather than introduce an additional dependency such as Apache Commons File Upload.



[[howto.spring-mvc.switch-off-dispatcherservlet]]
== Switch Off the Spring MVC DispatcherServlet

By default, all content is served from the root of your application (`/`).
If you would rather map to a different path, you can configure one as follows:

[configprops,yaml]
----
spring:
  mvc:
    servlet:
      path: "/mypath"
----

If you have additional servlets you can declare a javadoc:org.springframework.context.annotation.Bean[format=annotation] of type javadoc:jakarta.servlet.Servlet[] or javadoc:org.springframework.boot.web.servlet.ServletRegistrationBean[] for each and Spring Boot will register them transparently to the container.
It is also possible to use javadoc:org.springframework.boot.web.servlet.ServletRegistration[format=annotation] as an annotation-based alternative to javadoc:org.springframework.boot.web.servlet.ServletRegistrationBean[].
Because servlets are registered that way, they can be mapped to a sub-context of the javadoc:org.springframework.web.servlet.DispatcherServlet[] without invoking it.

Configuring the javadoc:org.springframework.web.servlet.DispatcherServlet[] yourself is unusual but if you really need to do it, a javadoc:org.springframework.context.annotation.Bean[format=annotation] of type javadoc:org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath[] must be provided as well to provide the path of your custom javadoc:org.springframework.web.servlet.DispatcherServlet[].



[[howto.spring-mvc.switch-off-default-configuration]]
== Switch Off the Default MVC Configuration

The easiest way to take complete control over MVC configuration is to provide your own javadoc:org.springframework.context.annotation.Configuration[format=annotation] with the javadoc:org.springframework.web.servlet.config.annotation.EnableWebMvc[format=annotation] annotation.
Doing so leaves all MVC configuration in your hands.



[[howto.spring-mvc.customize-view-resolvers]]
== Customize ViewResolvers

A javadoc:org.springframework.web.servlet.ViewResolver[] is a core component of Spring MVC, translating view names in javadoc:org.springframework.stereotype.Controller[format=annotation] to actual javadoc:org.springframework.web.servlet.View[] implementations.
Note that view resolvers are mainly used in UI applications, rather than REST-style services (a javadoc:org.springframework.web.servlet.View[] is not used to render a javadoc:org.springframework.web.bind.annotation.ResponseBody[format=annotation]).
There are many implementations of javadoc:org.springframework.web.servlet.ViewResolver[] to choose from, and Spring on its own is not opinionated about which ones you should use.
Spring Boot, on the other hand, installs one or two for you, depending on what it finds on the classpath and in the application context.
The javadoc:org.springframework.web.servlet.DispatcherServlet[] uses all the resolvers it finds in the application context, trying each one in turn until it gets a result.
If you add your own, you have to be aware of the order and in which position your resolver is added.

javadoc:org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration[] adds the following javadoc:org.springframework.web.servlet.ViewResolver[] beans to your context:

* An javadoc:org.springframework.web.servlet.view.InternalResourceViewResolver[] named '`defaultViewResolver`'.
  This one locates physical resources that can be rendered by using the `DefaultServlet` (including static resources and JSP pages, if you use those).
  It applies a prefix and a suffix to the view name and then looks for a physical resource with that path in the servlet context (the defaults are both empty but are accessible for external configuration through `spring.mvc.view.prefix` and `spring.mvc.view.suffix`).
  You can override it by providing a bean of the same type.
* A javadoc:org.springframework.web.servlet.view.BeanNameViewResolver[] named '`beanNameViewResolver`'.
  This is a useful member of the view resolver chain and picks up any beans with the same name as the javadoc:org.springframework.web.servlet.View[] being resolved.
  It should not be necessary to override or replace it.
* A javadoc:org.springframework.web.servlet.view.ContentNegotiatingViewResolver[] named '`viewResolver`' is added only if there *are* actually beans of type javadoc:org.springframework.web.servlet.View[] present.
  This is a composite resolver, delegating to all the others and attempting to find a match to the '`Accept`' HTTP header sent by the client.
  There is a useful https://spring.io/blog/2013/06/03/content-negotiation-using-views[blog about javadoc:org.springframework.web.servlet.view.ContentNegotiatingViewResolver[]] that you might like to study to learn more, and you might also look at the source code for detail.
  You can switch off the auto-configured javadoc:org.springframework.web.servlet.view.ContentNegotiatingViewResolver[] by defining a bean named '`viewResolver`'.
* If you use Thymeleaf, you also have a javadoc:org.thymeleaf.spring6.view.ThymeleafViewResolver[] named '`thymeleafViewResolver`'.
  It looks for resources by surrounding the view name with a prefix and suffix.
  The prefix is `spring.thymeleaf.prefix`, and the suffix is `spring.thymeleaf.suffix`.
  The values of the prefix and suffix default to '`classpath:/templates/`' and '`.html`', respectively.
  You can override javadoc:org.thymeleaf.spring6.view.ThymeleafViewResolver[] by providing a bean of the same name.
* If you use FreeMarker, you also have a javadoc:org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver[] named '`freeMarkerViewResolver`'.
  It looks for resources in a loader path (which is externalized to `spring.freemarker.templateLoaderPath` and has a default value of '`classpath:/templates/`') by surrounding the view name with a prefix and a suffix.
  The prefix is externalized to `spring.freemarker.prefix`, and the suffix is externalized to `spring.freemarker.suffix`.
  The default values of the prefix and suffix are empty and '`.ftlh`', respectively.
  You can override javadoc:org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver[] by providing a bean of the same name.
  FreeMarker variables can be customized by defining a bean of type javadoc:org.springframework.boot.autoconfigure.freemarker.FreeMarkerVariablesCustomizer[].
* If you use Groovy templates (actually, if `groovy-templates` is on your classpath), you also have a javadoc:org.springframework.web.servlet.view.groovy.GroovyMarkupViewResolver[] named '`groovyMarkupViewResolver`'.
  It looks for resources in a loader path by surrounding the view name with a prefix and suffix (externalized to `spring.groovy.template.prefix` and `spring.groovy.template.suffix`).
  The prefix and suffix have default values of '`classpath:/templates/`' and '`.tpl`', respectively.
  You can override javadoc:org.springframework.web.servlet.view.groovy.GroovyMarkupViewResolver[] by providing a bean of the same name.
* If you use Mustache, you also have a javadoc:org.springframework.boot.web.servlet.view.MustacheViewResolver[] named '`mustacheViewResolver`'.
  It looks for resources by surrounding the view name with a prefix and suffix.
  The prefix is `spring.mustache.prefix`, and the suffix is `spring.mustache.suffix`.
  The values of the prefix and suffix default to '`classpath:/templates/`' and '`.mustache`', respectively.
  You can override javadoc:org.springframework.boot.web.servlet.view.MustacheViewResolver[] by providing a bean of the same name.

For more detail, see the following sections:

* {code-spring-boot-autoconfigure-src}/web/servlet/WebMvcAutoConfiguration.java[`WebMvcAutoConfiguration`]
* {code-spring-boot-autoconfigure-src}/thymeleaf/ThymeleafAutoConfiguration.java[`ThymeleafAutoConfiguration`]
* {code-spring-boot-autoconfigure-src}/freemarker/FreeMarkerAutoConfiguration.java[`FreeMarkerAutoConfiguration`]
* {code-spring-boot-autoconfigure-src}/groovy/template/GroovyTemplateAutoConfiguration.java[`GroovyTemplateAutoConfiguration`]



[[howto.spring-mvc.customize-whitelabel-error-page]]
== Customize the '`whitelabel`' Error Page

Spring Boot installs a '`whitelabel`' error page that you see in a browser client if you encounter a server error (machine clients consuming JSON and other media types should see a sensible response with the right error code).

NOTE: Set `server.error.whitelabel.enabled=false` to switch the default error page off.
Doing so restores the default of the servlet container that you are using.
Note that Spring Boot still tries to resolve the error view, so you should probably add your own error page rather than disabling it completely.

Overriding the error page with your own depends on the templating technology that you use.
For example, if you use Thymeleaf, you can add an `error.html` template.
If you use FreeMarker, you can add an `error.ftlh` template.
In general, you need a javadoc:org.springframework.web.servlet.View[] that resolves with a name of `error` or a javadoc:org.springframework.stereotype.Controller[format=annotation] that handles the `/error` path.
Unless you replaced some of the default configuration, you should find a javadoc:org.springframework.web.servlet.view.BeanNameViewResolver[] in your javadoc:org.springframework.context.ApplicationContext[], so a javadoc:org.springframework.context.annotation.Bean[format=annotation] named `error` would be one way of doing that.
See {code-spring-boot-autoconfigure-src}/web/servlet/error/ErrorMvcAutoConfiguration.java[`ErrorMvcAutoConfiguration`] for more options.

See also the section on xref:reference:web/servlet.adoc#web.servlet.spring-mvc.error-handling[] for details of how to register handlers in the servlet container.
