Spring MVC中的ViewResolver指南

2023/05/19

1. 概述

所有MVC框架都提供了一种处理视图的方法。

Spring通过视图解析器实现这一点,这使你能够在浏览器中呈现模型,而无需将实现绑定到特定的视图技术。

ViewResolver将视图名称映射到实际视图。

Spring框架附带了很多视图解析器,例如InternalResourceViewResolver、BeanNameViewResolver等等。

本教程展示了如何设置最常见的视图解析器,以及如何在同一配置中使用多个ViewResolver。

2. Spring Web配置

我们使用@EnableWebMvc、@Configuration和@ComponentScan标注我们的配置类:


@EnableWebMvc
@ComponentScan(basePackages = {"cn.tuyucheng.web.controller"})
@Configuration
public class WebConfig implements WebMvcConfigurer {

}

3. InternalResourceViewResolver

这个ViewResolver允许我们为视图名称设置前缀或后缀等属性,以生成最终的视图页面URL:

public class WebConfig implements WebMvcConfigurer {

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

为了简单起见,我们不需要控制器来处理请求。

我们只需要一个简单的jsp页面,放在配置中定义的/WEB-INF/view文件夹中:


<html>
<head></head>

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

4. BeanNameViewResolver

这是ViewResolver的一个实现,它将视图名称解析为当前应用程序上下文中的bean名称。每个这样的视图都可以定义为XML或Java配置中的bean。

首先,我们将BeanNameViewResolver添加到之前的配置类中:

public class WebConfig implements WebMvcConfigurer {

    @Bean
    public BeanNameViewResolver beanNameViewResolver() {
        return new BeanNameViewResolver();
    }
}

定义了ViewResolver之后,我们需要定义View类型的bean,以便DispatcherServlet可以执行它来呈现视图:

public class WebConfig implements WebMvcConfigurer {

    @Bean
    public View sample() {
        return new JstlView("/WEB-INF/view/sample.jsp");
    }
}

这是控制器类中相应的处理程序方法:


@Controller
public class SampleController {

    @GetMapping("/sample")
    public String showForm() {
        return "sample";
    }
}

在控制器方法中,视图名称作为“sample”返回,这意味着该处理程序方法的视图解析为包含/WEB-INF/view/sample.jsp URL的JstlView类。

5. 优先级

Spring MVC还支持多视图解析器

这允许你在某些情况下覆盖特定视图。我们可以通过在配置中添加多个解析器来简单地链接视图解析器。

然后,我们需要为这些解析器定义一个顺序。order属性用于定义解析器链中调用的顺序。order属性值越大,视图解析器在链中的优先级越低。

要定义顺序,我们可以将以下代码添加到视图解析器的配置中:

bean.setOrder(0);

注意顺序优先级,InternalResourceViewResolver应该具有更高的顺序 - 因为它旨在表示非常明确的映射。 如果其他解析器具有更高的顺序,则可能永远不会调用InternalResourceViewResolver。

6. Spring Boot

使用Spring Boot时,WebMvcAutoConfiguration会在我们的应用程序上下文中自动配置 InternalResourceViewResolver和BeanNameViewResolver bean。

此外,为模板引擎添加相应的启动器依赖会减少我们必须进行的手动配置。

例如,通过将spring-boot-starter-thymeleaf依赖添加到我们的pom.xml中,Thymeleaf被启用,并且不需要额外的配置:


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    <version>${spring-boot-starter-thymeleaf.version}</version>
</dependency>

该启动器依赖项在我们的应用程序上下文中配置一个名为thymeleafViewResolver的ThymeleafViewResolver bean。 我们可以通过提供一个同名的bean来覆盖自动配置的ThymeleafViewResolver。

Thymeleaf视图解析器通过设置视图的前缀和后缀。前缀和后缀的默认值分别是“classpath:/templates/”和“.html”。

Spring Boot还提供了一个选项,可以通过分别设置spring.thymeleaf.prefix和spring.thymeleaf.suffix属性来更改前缀和后缀的默认值。

此外,还可以添加groovy-templates、freemarker和mustache模板引擎的启动器依赖项, 我们可以通过它们来使用Spring Boot自动配置相应的视图解析器。

DispatcherServlet使用它在应用程序上下文中找到的所有视图解析器,并尝试每一个,直到得到结果,因此如果我们添加自己的视图解析器,这些视图解析器的顺序变得非常重要。

7. 总结

在本教程中,我们使用Java配置了一系列视图解析器。通过使用setOrder()方法,我们可以设置它们的调用顺序。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章