A Guide to the ViewResolver in Spring MVC

1. Overview

All MVC frameworks provide a way of working with views.

Spring does that via the view resolvers, which enable you to render models in the browser without tying the implementation to a specific view technology.

The ViewResolver maps view names to actual views.

And the Spring framework comes with quite a few view resolvers e.g. InternalResourceViewResolverXmlViewResolverResourceBundleViewResolver and a few others.

This is a simple tutorial showing how to set up the most common view resolvers and how to use multiple ViewResolver in the same configuration.

2. The Spring Web Configuration

Let’s start with the web configuration; we’ll annotate it with @EnableWebMvc@Configuration and @ComponentScan:

@EnableWebMvc
@Configuration
@ComponentScan("com.maixuanviet.web")
public class WebConfig implements WebMvcConfigurer {
    // All web configuration will go here
}

It’s here that we’ll set up our view resolver in the configuration.

3. Add an InternalResourceViewResolver

This ViewResolver allows us to set properties such as prefix or suffix to the view name to generate the final view page URL:

@Bean
public ViewResolver internalResourceViewResolver() {
    InternalResourceViewResolver bean = new InternalResourceViewResolver();
    bean.setViewClass(JstlView.class);
    bean.setPrefix("/WEB-INF/view/");
    bean.setSuffix(".jsp");
    return bean;
}

For such simplicity of the example, we don’t need a controller to process the request.

We only need a simple jsp page, placed in the /WEB-INF/view folder as defined in the configuration:

<html>
    <head></head>
    <body>
        <h1>This is the body of the sample view</h1>
    </body>
</html>

4. Add a ResourceBundleViewResolver

As the name of this resolver suggest a ResourceBundleViewResolver uses bean definitions in a ResourceBundle.

First, we add the ResourceBundleViewResolver to the previous configuration:

@Bean
public ViewResolver resourceBundleViewResolver() {
    ResourceBundleViewResolver bean = new ResourceBundleViewResolver();
    bean.setBasename("views");
    return bean;
}

The bundle is typically defined in a properties file, located in the classpath. Below is the views.properties file:

sample.(class)=org.springframework.web.servlet.view.JstlView
sample.url=/WEB-INF/view/sample.jsp

We can use the simple jsp page defined in the above example for this configuration as well.

5. Add an XmlViewResolver

This implementation of ViewResolver accepts a configuration file written in XML with the same DTD as Spring’s XML bean factories:

@Bean
public ViewResolver xmlViewResolver() {
    XmlViewResolver bean = new XmlViewResolver();
    bean.setLocation(new ClassPathResource("views.xml"));
    return bean;
}

Below is the configuration file, views.xml:

<bean id="xmlConfig" class="org.springframework.web.servlet.view.JstlView">
    <property name="url" value="/WEB-INF/view/xmlSample.jsp" />
</bean>

As for the previous examples we can use our simple jsp page defined previously.

6. Chaining ViewResolvers and Define an Order Priority

Spring MVC also supports multiple view resolvers.

This allow you to override specific views in some circumstances. We can simply chain view resolvers by adding more than one resolver to the configuration.

Once we’ve done that, we’ll need to define an order for these resolvers. The order property is used to define which is the order of invocations in the chain. The higher the order property (largest order number), the later the view resolver is positioned in the chain.

To define the order we can add the follow line of code to the configuration of the our view resolvers:

bean.setOrder(0);

Be careful on the order priority as the InternalResourceViewResolver should have a higher order – because it’s intended to represent a very explicit mapping. And if other resolvers have a higher order, then the InternalResourceViewResolver might never be invoked.

7. Conclusion

In this tutorial we configured a chain of view resolvers using Java configuration. By playing with the order priority we can set the order of their invocation.

The implementation of this simple tutorial can be found in the github project.