> For the complete documentation index, see [llms.txt](https://hantsy.gitbook.io/build-a-restful-app-with-spring-mvc-and-angularjs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hantsy.gitbook.io/build-a-restful-app-with-spring-mvc-and-angularjs/getting-started/mvc.md).

# Configure Spring WebMVC

Firstly add Spring WebMvc related dependenices into *pom.xml*.

```markup
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
</dependency>
```

To bootstrap a Spring MVC application, you have to enable Spring built-in `DisptachServlet`.

Serlvet 3.0 provides a new feature *ServletInitializer* to configure web applciation without *web.xml*.

Spring has its *WebApplicationInitializer* interface, there are a few classes implement this interface, `AbstractAnnotationConfigDispatcherServletInitializer` includes configuration of Spring Dispatch Servlet, and leaves some room to customize `DispatchServlet`.

Declare a `AbstractAnnotationConfigDispatcherServletInitializer` bean.

```java
@Order(0)
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

   @Override
   protected Class<?>[] getRootConfigClasses() {
       return new Class[] {
               AppConfig.class, //
               DataSourceConfig.class, //            
               JpaConfig.class, //
               DataJpaConfig.class,//
               SecurityConfig.class,//   
               Jackson2ObjectMapperConfig.class,//
               MessageSourceConfig.class
       };
   }

   @Override
   protected Class<?>[] getServletConfigClasses() {
       return new Class[] {
           WebConfig.class, //
           SwaggerConfig.class //
       };
   }

   @Override
   protected String[] getServletMappings() {
       return new String[] { "/" };
   }

   @Override
   protected Filter[] getServletFilters() {
       CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
       encodingFilter.setEncoding("UTF-8");
       encodingFilter.setForceEncoding(true);

       return new Filter[] { encodingFilter };
   }

}
```

`getRootConfigClasses` specifies the configuration classes should be loaded for the Spring infrastrucuture.

`getServletConfigClasses` specifies the configurations depend on Servlet specification, esp, web mvc related configurations.

`getServletMappings` is the Spring `DispatchServlet` mapping URL pattern.

`getServletFilters` are those Web Filters will be applied on the Spring `DispatchServlet`.

Spring MVC `DispatchServlet` is configured in the super classes, explore the details if you are interested in it.

In `getServletConfigClasses`, we specify a `WebConfig` will be loaded, which is responsible for configuring Spring MVC in details, including resource handling, view, view resolvers etc.

A classic `WebConfig` looks like.

```java
public class WebConfig extends WebMvcConfigurerAdapter {

}
```

Generally, `WebMvcConfigurerAdapter` is the extension point left for users to use for customizing MVC configurations.

Spring Data project provides a `SpringDataWebConfiguration` which is a subclass of `WebMvcConfigurerAdapter` and adds pagination, sort, and domain object conversion support. Open the source code of `SpringDataWebConfiguration` and research yourself.

The following is the full source code of `WebConfig`.

```java
@Configuration
@EnableWebMvc
@ComponentScan(
        basePackageClasses = {Constants.class},
        useDefaultFilters = false,
        includeFilters = {
            @Filter(
                    type = FilterType.ANNOTATION,
                    value = {
                        Controller.class,
                        RestController.class,
                        ControllerAdvice.class
                    }
            )
        }
)
public class WebConfig extends SpringDataWebConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(WebConfig.class);

    @Inject
    private ObjectMapper objectMapper;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        registry.addResourceHandler("/swagger-ui.html")
                .addResourceLocations("classpath:META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:META-INF/resources/webjars/");
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {

    }

    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
        exceptionResolvers.add(exceptionHandlerExceptionResolver());
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorParameter(false);
        configurer.favorPathExtension(false);
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        List<HttpMessageConverter<?>> messageConverters = messageConverters();
        converters.addAll(messageConverters);
    }

    @Bean
    public ExceptionHandlerExceptionResolver exceptionHandlerExceptionResolver() {
        ExceptionHandlerExceptionResolver exceptionHandlerExceptionResolver = new ExceptionHandlerExceptionResolver();
        exceptionHandlerExceptionResolver.setMessageConverters(messageConverters());

        return exceptionHandlerExceptionResolver;
    }

    private List<HttpMessageConverter<?>> messageConverters() {
        List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();

        MappingJackson2HttpMessageConverter jackson2Converter = new MappingJackson2HttpMessageConverter();
        jackson2Converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON));
        jackson2Converter.setObjectMapper(objectMapper);

        messageConverters.add(jackson2Converter);
        return messageConverters;
    }

}
```

* `@EnableWebMvc` tells Spring to enable Spring MVC.
* `@ComponentScan` uses a filter to select Spring MVC related classes to be activated.
* `addResourceHandlers` configure how to handle static resources.
* `addViewControllers` leave places to configure view resolver to render specific views.
* `configureHandlerExceptionResolvers` specifies exception handling stretagy.
* `configureMessageConverters` configure `HttpMessageConverter` will be used for serialization and deserialization.

I would like use `application/json` as default content type, and uses Jackson to serialize and deserialize messages.

Configure a Jackson ObjectMapper as you need.

```java
@Configuration
public class Jackson2ObjectMapperConfig {

    @Bean
    public ObjectMapper objectMapper() {

        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.serializationInclusion(Include.NON_EMPTY);
        builder.featuresToDisable(
               // SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
                DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES,
                DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        builder.featuresToEnable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

        return builder.build();
    }
}
```

`Jackson2ObjectMapperBuilder` provides fluent APIs to configure which features will be enabled or disabled for serialization and deserialization. For the complete configurable options, check the javadocs of `SerializationFeature` and `DeserializationFeature`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hantsy.gitbook.io/build-a-restful-app-with-spring-mvc-and-angularjs/getting-started/mvc.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
