On this page
74. Spring MVC
Any Spring @RestController
in a Spring Boot application should render JSON response by default as long as Jackson2 is on the classpath. For example:
@RestController
public class MyController {
@RequestMapping("/thing")
public MyThing thing() {
return new MyThing();
}
}
As long as MyThing
can be serialized by Jackson2 (e.g. a normal POJO or Groovy object) then localhost:8080/thing
will serve a JSON representation of it by default. Sometimes in a browser you might see XML responses because browsers tend to send accept headers that prefer XML.
If you have the Jackson XML extension (jackson-dataformat-xml
) on the classpath, it will be used to render XML responses and the very same example as we used for JSON would work. To use it, add the following dependency to your project:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
You may also want to add a dependency on Woodstox. It’s faster than the default StAX implementation provided by the JDK and also adds pretty print support and improved namespace handling:
<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>woodstox-core-asl</artifactId>
</dependency>
If Jackson’s XML extension is not available, JAXB (provided by default in the JDK) will be used, with the additional requirement to have MyThing
annotated as @XmlRootElement
:
@XmlRootElement
public class MyThing {
private String name;
// .. getters and setters
}
To get the server to render XML instead of JSON you might have to send an Accept: text/xml
header (or use a browser).
Spring MVC (client and server side) uses HttpMessageConverters
to negotiate content conversion in an HTTP exchange. If Jackson is on the classpath you already get the default converter(s) provided by Jackson2ObjectMapperBuilder
, an instance of which is auto-configured for you.
The ObjectMapper
(or XmlMapper
for Jackson XML converter) instance created by default has the following customized properties:
MapperFeature.DEFAULT_VIEW_INCLUSION
is disabledDeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
is disabled
Spring Boot has also some features to make it easier to customize this behavior.
You can configure the ObjectMapper
and XmlMapper
instances using the environment. Jackson provides an extensive suite of simple on/off features that can be used to configure various aspects of its processing. These features are described in six enums in Jackson which map onto properties in the environment:
Jackson enum | Environment property |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
For example, to enable pretty print, set spring.jackson.serialization.indent_output=true
. Note that, thanks to the use of relaxed binding, the case of indent_output
doesn’t have to match the case of the corresponding enum constant which is INDENT_OUTPUT
.
This environment-based configuration is applied to the auto-configured Jackson2ObjectMapperBuilder
bean, and will apply to any mappers created using the builder, including the auto-configured ObjectMapper
bean.
The context’s Jackson2ObjectMapperBuilder
can be customized by one or more Jackson2ObjectMapperBuilderCustomizer
beans. Such customizer beans can be ordered and Boot’s own customizer has an order of 0, allowing additional customization to be applied both before and after Boot’s customization.
Any beans of type com.fasterxml.jackson.databind.Module
will be automatically registered with the auto-configured Jackson2ObjectMapperBuilder
and applied to any ObjectMapper
instances that it creates. This provides a global mechanism for contributing custom modules when you add new features to your application.
If you want to replace the default ObjectMapper
completely, either define a @Bean
of that type and mark it as @Primary
, or, if you prefer the builder-based approach, define a Jackson2ObjectMapperBuilder
@Bean
. Note that in either case this will disable all auto-configuration of the ObjectMapper
.
If you provide any @Beans
of type MappingJackson2HttpMessageConverter
then they will replace the default value in the MVC configuration. Also, a convenience bean is provided of type HttpMessageConverters
(always available if you use the default MVC configuration) which has some useful methods to access the default and user-enhanced message converters.
See also the Section 74.4, “Customize the @ResponseBody rendering” section and the WebMvcAutoConfiguration
source code for more details.
Spring uses HttpMessageConverters
to render @ResponseBody
(or responses from @RestController
). You can contribute additional converters by simply adding beans of that type in a Spring Boot context. If a bean you add is of a type that would have been included by default anyway (like MappingJackson2HttpMessageConverter
for JSON conversions) then it will replace the default value. A convenience bean is provided of type HttpMessageConverters
(always available if you use the default MVC configuration) which has some useful methods to access the default and user-enhanced message converters (useful, for example if you want to manually inject them into a custom RestTemplate
).
As in normal MVC usage, any WebMvcConfigurerAdapter
beans that you provide can also contribute converters by overriding the configureMessageConverters
method, but 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 Spring Boot default MVC configuration by providing your own @EnableWebMvc
configuration, then you can take control completely and do everything manually using getMessageConverters
from WebMvcConfigurationSupport
.
See the WebMvcAutoConfiguration
source code for more details.
Spring Boot embraces the Servlet 3 javax.servlet.http.Part
API to support uploading files. By default Spring Boot configures Spring MVC with a maximum file of 1MB per file and a maximum of 10MB of file data in a single request. You may override these values, as well as the location to which intermediate data is stored (e.g., to the /tmp
directory) and the threshold past which data is flushed to disk by using the properties exposed in the MultipartProperties
class. If you want to specify that files be unlimited, for example, set the spring.http.multipart.max-file-size
property to -1
.
The multipart support is helpful when you want to receive multipart encoded file data as a @RequestParam
-annotated parameter of type MultipartFile
in a Spring MVC controller handler method.
See the MultipartAutoConfiguration
source for more details.
Spring Boot wants to serve all content from the root of your application /
down. If you would rather map your own servlet to that URL you can do it, but of course you may lose some of the other Boot MVC features. To add your own servlet and map it to the root resource just declare a @Bean
of type Servlet
and give it the special bean name dispatcherServlet
(You can also create a bean of a different type with that name if you want to switch it off and not replace it).
The easiest way to take complete control over MVC configuration is to provide your own @Configuration
with the @EnableWebMvc
annotation. This will leave all MVC configuration in your hands.
A ViewResolver
is a core component of Spring MVC, translating view names in @Controller
to actual View
implementations. Note that ViewResolvers
are mainly used in UI applications, rather than REST-style services (a View
is not used to render a @ResponseBody
). There are many implementations of 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 DispatcherServlet
uses all the resolvers it finds in the application context, trying each one in turn until it gets a result, so if you are adding your own you have to be aware of the order and in which position your resolver is added.
WebMvcAutoConfiguration
adds the following ViewResolvers
to your context:
- An
InternalResourceViewResolver
with bean id ‘defaultViewResolver’. This one locates physical resources that can be rendered using theDefaultServlet
(e.g. static resources and JSP pages if you are using 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 (defaults are both empty, but accessible for external configuration viaspring.mvc.view.prefix
andspring.mvc.view.suffix
). It can be overridden by providing a bean of the same type. - A
BeanNameViewResolver
with id ‘beanNameViewResolver’. This is a useful member of the view resolver chain and will pick up any beans with the same name as theView
being resolved. It shouldn’t be necessary to override or replace it. - A
ContentNegotiatingViewResolver
with id ‘viewResolver’ is only added if there are actually beans of typeView
present. This is a ‘master’ 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 blog aboutContentNegotiatingViewResolver
that you might like to study to learn more, and also look at the source code for detail. You can switch off the auto-configuredContentNegotiatingViewResolver
by defining a bean named ‘viewResolver’. - If you use Thymeleaf you will also have a
ThymeleafViewResolver
with id ‘thymeleafViewResolver’. It looks for resources by surrounding the view name with a prefix and suffix (externalized tospring.thymeleaf.prefix
andspring.thymeleaf.suffix
, defaults ‘classpath:/templates/’ and ‘.html’ respectively). It can be overridden by providing a bean of the same name. - If you use FreeMarker you will also have a
FreeMarkerViewResolver
with id ‘freeMarkerViewResolver’. It looks for resources in a loader path (externalized tospring.freemarker.templateLoaderPath
, default ‘classpath:/templates/’) by surrounding the view name with a prefix and suffix (externalized tospring.freemarker.prefix
andspring.freemarker.suffix
, with empty and ‘.ftl’ defaults respectively). It can be overridden by providing a bean of the same name. - If you use Groovy templates (actually if groovy-templates is on your classpath) you will also have a
GroovyMarkupViewResolver
with id ‘groovyMarkupViewResolver’. It looks for resources in a loader path by surrounding the view name with a prefix and suffix (externalized tospring.groovy.template.prefix
andspring.groovy.template.suffix
, defaults ‘classpath:/templates/’ and ‘.tpl’ respectively). It can be overridden by providing a bean of the same name.
Check out WebMvcAutoConfiguration
, ThymeleafAutoConfiguration
, FreeMarkerAutoConfiguration
and GroovyTemplateAutoConfiguration
By default, spring-boot-starter-thymeleaf
uses Thymeleaf 2.1. If you are using the spring-boot-starter-parent
, you can use Thymeleaf 3 by overriding the thymeleaf.version
and thymeleaf-layout-dialect.version
properties, for example:
<properties>
<thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.1.1</thymeleaf-layout-dialect.version>
</properties>
Note | |
---|---|
if you are managing dependencies yourself, look at |
To avoid a warning message about the HTML 5 template mode being deprecated and the HTML template mode being used instead, you may also want to explicitly configure spring.thymeleaf.mode
to be HTML
, for example:
spring.thymeleaf.mode: HTML
Please refer to the Thymeleaf 3 sample to see this in action.
If you are using any of the other auto-configured Thymeleaf Extras (Spring Security, Data Attribute, or Java 8 Time) you should also override each of their versions to one that is compatible with Thymeleaf 3.0.