Spring MVC View resolver - Tuong-Nguyen/Spring GitHub Wiki

Overview

  • Enable to render models in the browser without any implementation to specify view.
  • Maps view names to actual views
  • Built-in view resolvers:
    • InternalResourceViewResolver
    • XmlViewResolver
    • ...

Types

InternalResourceViewResolver

Allow use to set properties, such as prefix or sufix to the view name to generate the view page

Use cases

Put JSP files as views under WEB-INF, to hide them from direct access (entered URL). Only controllers will be able to access them.

Example

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setExposeContextBeansAsAttributes(true);
        return resolver;
    }

XmlViewResolver

  • Accepts a configuration file written in XML with the same DTD as Spring's XML bean factories
  • XML file default location is /WEB-INF/views.xml
  • Implement Ordered interface to allow for flexible participation in ViewResolver chaining

Use cases

Some special views could be defined via XmlViewResolver (give it a order value) while all remaining views could be resolved by other view resolver

Example

  • Define a bean that return XmlViewResolver as ViewResolver in WebConfig
  • Create a views.xml in /WEB-INF/views.xml by default or in resources (path src/main/resources)
     <bean id="home" class="org.springframework.web.servlet.view.RedirectView">
         <property name="url" value="http://www.google.com" />
     </bean>
    • If XmlViewResolver is applied, when HomeController runs, the browser is redirected to Google website
  • We can set location for dedicated XML file
  • Set order
    @Bean
    public ViewResolver xmlViewResolver() {
        XmlViewResolver resolver = new XmlViewResolver();
        Resource resource = new ClassPathResource("/views.xml"); // src/main/resources/views.xml
        resolver.setLocation(resource);
        resolver.setOrder(1);
        return resolver;
    }

ContentNegotiatingViewResolver

  • Delegates to other ViewResolver to resolve a view based on the request file name or Accept header
  • Set order for the view resolvers to help work properly.
  • View resolver uses request media type to select a suitable view for request.

Use cases

Dishes out JSON, XML or other formatted data with the same components. For example: we have data of a user list. For each type of request user makes, our application returns corresponding formatted data.

  • /users.xml return users list in XML format
  • /users.json return users list in JSON format
  • /users return users list in HTML format

Example

  • Override configureContentNegotiation, set default content is html, supports xml and json only.
  • Creates a ContentNegotiationManager and configures it with one or more ContentNegotiationStrategy instances.
  • The order in which strategies are configured is fixed
    @Override
    public void configureContentNegotiation
            (ContentNegotiationConfigurer configurer) {
        configurer
                .defaultContentType(MediaType.TEXT_HTML)
                .mediaType("xml", MediaType.APPLICATION_XML)
                .mediaType("json", MediaType.APPLICATION_JSON);
    }
  • Define a bean that return ContentNegotiatingViewResolver as ViewResolver in WebConfig
    @Bean
    public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager){
        ContentNegotiatingViewResolver cnViewResolver = new ContentNegotiatingViewResolver();
        cnViewResolver.setContentNegotiationManager(manager);
        return cnViewResolver;
    }

Ref: https://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc

Custom view resolver (JsonViewResolver)

Prerequisite

  • Import com.fasterxml.jackson.core library
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.7</version>
        </dependency>
  • Must do:
    • Open Project Structure, go to Artifacts, add all com.fasterxml.jackson.core:jackson-xxxx libraries to output
    • Build Artifacts

Implementation

  • Define a custom view resolver, ex: JsonViewResolver, that implement ViewResolver
public class JsonViewResolver implements ViewResolver {
    @Override
    public View resolveViewName(String viewName, Locale locale)
            throws Exception {
        MappingJackson2JsonView view = new MappingJackson2JsonView();
        view.setPrettyPrint(true);
        return view;
    }
}
  • Add JsonViewResolver bean
    @Bean
    public ViewResolver jsonViewResolver(){
        JsonViewResolver resolver = new JsonViewResolver();
        return resolver;
    }
  • Add @XmlRootElement(name="user") before the class model we need to get XML formatted data
⚠️ **GitHub.com Fallback** ⚠️