Bootstrap

Spring视图解析(ViewResolver)

在 Spring MVC 框架中,视图解析(ViewResolver)是一个重要的组件,负责将逻辑视图名称解析为具体的视图技术(如 JSP、Thymeleaf、Freemarker 等)。视图解析器使得控制器可以返回一个逻辑视图名称,而不是具体的视图资源路径,从而提高了代码的灵活性和可维护性。

1. 视图解析器的基本概念

1.1 逻辑视图名称(Logical View Name)
  • 定义:控制器方法返回的字符串,表示一个逻辑视图名称。这个名称不是具体的视图资源路径,而是由视图解析器解析为具体的视图。
  • 示例:控制器方法返回 "home",表示逻辑视图名称为 home
1.2 视图解析器(ViewResolver)
  • 定义:视图解析器是一个接口,负责将逻辑视图名称解析为具体的视图对象。Spring 提供了多种视图解析器实现,每种实现支持不同的视图技术。
  • 接口org.springframework.web.servlet.ViewResolver

2. 常见的视图解析器实现

2.1 InternalResourceViewResolver
  • 用途:用于解析 JSP 视图。
  • 配置
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Bean
        public ViewResolver internalResourceViewResolver() {
            InternalResourceViewResolver resolver = new InternalResourceViewResolver();
            resolver.setPrefix("/WEB-INF/views/");
            resolver.setSuffix(".jsp");
            return resolver;
        }
    }
  • 示例
    • 控制器方法返回 "home",解析为 /WEB-INF/views/home.jsp
2.2 ThymeleafViewResolver
  • 用途:用于解析 Thymeleaf 视图。
  • 配置
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Bean
        public SpringTemplateEngine templateEngine() {
            SpringTemplateEngine templateEngine = new SpringTemplateEngine();
            templateEngine.setTemplateResolver(templateResolver());
            return templateEngine;
        }
    
        @Bean
        public TemplateResolver templateResolver() {
            TemplateResolver resolver = new ServletContextTemplateResolver();
            resolver.setPrefix("/WEB-INF/templates/");
            resolver.setSuffix(".html");
            resolver.setTemplateMode("HTML5");
            return resolver;
        }
    
        @Bean
        public ViewResolver thymeleafViewResolver() {
            ThymeleafViewResolver resolver = new ThymeleafViewResolver();
            resolver.setTemplateEngine(templateEngine());
            return resolver;
        }
    }
  • 示例
    • 控制器方法返回 "home",解析为 /WEB-INF/templates/home.html
2.3 FreeMarkerViewResolver
  • 用途:用于解析 FreeMarker 视图。
  • 配置
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Bean
        public FreeMarkerConfigurer freeMarkerConfigurer() {
            FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
            configurer.setTemplateLoaderPath("/WEB-INF/freemarker/");
            return configurer;
        }
    
        @Bean
        public ViewResolver freemarkerViewResolver() {
            FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
            resolver.setPrefix("");
            resolver.setSuffix(".ftl");
            return resolver;
        }
    }
  • 示例
    • 控制器方法返回 "home",解析为 /WEB-INF/freemarker/home.ftl
2.4 TilesViewResolver
  • 用途:用于解析 Apache Tiles 视图。
  • 配置
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Bean
        public UrlBasedViewResolver tilesViewResolver() {
            UrlBasedViewResolver resolver = new UrlBasedViewResolver();
            resolver.setViewClass(TilesView.class);
            return resolver;
        }
    
        @Bean
        public TilesConfigurer tilesConfigurer() {
            TilesConfigurer configurer = new TilesConfigurer();
            configurer.setDefinitions(new String[] {"/WEB-INF/tiles.xml"});
            return configurer;
        }
    }
  • 示例
    • 控制器方法返回 "home",解析为 Tiles 定义中的 home 视图。

3. 视图解析器的配置

3.1 XML 配置
  • 示例
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
3.2 Java 配置
  • 示例
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Bean
        public ViewResolver internalResourceViewResolver() {
            InternalResourceViewResolver resolver = new InternalResourceViewResolver();
            resolver.setPrefix("/WEB-INF/views/");
            resolver.setSuffix(".jsp");
            return resolver;
        }
    }

4. 多视图解析器

在某些情况下,可能需要使用多个视图解析器。Spring 允许配置多个视图解析器,并按顺序进行解析。

示例

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Bean
    public ViewResolver thymeleafViewResolver() {
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateEngine(templateEngine());
        resolver.setOrder(1); // 设置优先级
        return resolver;
    }

    @Bean
    public ViewResolver internalResourceViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setOrder(2); // 设置优先级
        return resolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver());
        return templateEngine;
    }

    @Bean
    public TemplateResolver templateResolver() {
        TemplateResolver resolver = new ServletContextTemplateResolver();
        resolver.setPrefix("/WEB-INF/templates/");
        resolver.setSuffix(".html");
        resolver.setTemplateMode("HTML5");
        return resolver;
    }
}

5. 视图解析器的工作流程

  1. 控制器返回逻辑视图名称:控制器方法返回一个逻辑视图名称,例如 "home"
  2. 视图解析器链:Spring 容器按照配置的顺序遍历视图解析器链。
  3. 解析逻辑视图名称:每个视图解析器尝试将逻辑视图名称解析为具体的视图对象。
  4. 返回视图对象:第一个成功解析逻辑视图名称的视图解析器返回具体的视图对象。
  5. 渲染视图:Spring MVC 将模型数据传递给视图对象,并渲染视图。

总结

Spring MVC 中的视图解析器(ViewResolver)是一个重要的组件,负责将逻辑视图名称解析为具体的视图技术。Spring 提供了多种视图解析器实现,每种实现支持不同的视图技术,如 JSP、Thymeleaf、FreeMarker 和 Apache Tiles。通过合理配置视图解析器,可以提高代码的灵活性和可维护性,简化视图管理。多视图解析器的配置使得在一个项目中使用多种视图技术成为可能。

;