SpringMVC(七)_视图和视图解析器

         前言:本文主要介绍SpringMVC如何解析视图,以及通过自定义视图解析器实现视图解析。

1. SpringMVC解析视图的流程

SpringMVC(七)_视图和视图解析器        分析上述流程,可以总结出以下三个要点:

  • 请求处理方法执行完成后,最终返回一个 ModelAndView对象。对于那些返回 String,View 或 ModeMap 等类型的处理方法,Spring MVC 也会在内部将它们装配成一个ModelAndView 对象,它包含了逻辑名和模型对象的视图;
  • Spring MVC借助视图解析器(ViewResolver)得到最终的视图对象(View),最终的视图可以是JSP ,也可能是Excel、JFreeChart 等各种表现形式的视图;
  • 对于最终究竟采取何种视图对象对模型数据进行渲染,处理器并不关心,处理器工作重点聚焦在生产模型数据的工作上,从而实现 MVC 的充分解耦;

 2. 简述视图

       视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给客户。为了实现视图模型和具体实现技术的解耦,Spring在org.springframework.web.servlet 包中定义了一个高度抽象的 View接口:

SpringMVC(七)_视图和视图解析器       视图对象由视图解析器负责实例化。由于视图是无状态的,所以他们不会有线程安全的问题,常用的视图用:

SpringMVC(七)_视图和视图解析器

 

3. 简述视图解析器

        SpringMVC 为逻辑视图名的解析提供了不同的策略,可以在 Spring WEB 上下文中配置一种或多种解析策略,并指定他们之间的先后顺序。每一种映射策略对应一个具体的视图解析器实现类。视图解析器的作用比较单一:将逻辑视图解析为一个具体的视图对象,所有的视图解析器都必须实现 ViewResolver 接口:

SpringMVC(七)_视图和视图解析器        常见的视图解析器实现类:

SpringMVC(七)_视图和视图解析器          对于上述视图解析器实现类的几点说明:

  • 程序员可以选择一种视图解析器或混用多种视图解析器;
  • 每个视图解析器都实现了 Ordered 接口并开放出一个 order 属性,可以通过 order 属性指定解析器的优先顺序,order 越小优先级越高;
  • SpringMVC 会按视图解析器顺序的优先顺序对逻辑视图名进行解析,直到解析成功并返回视图对象,否则将抛出 ServletException 异常。

4. 基本配置

        下面输出相关demo,实现转发、重定向、组合使用视图解析器。先看SpringMVC配置文件中的相关配置:

<!-- 定义视图解析器(此处针对Jsp) -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!-- 所有URI的前缀. -->
    <property name="prefix" value="/views/"></property>
    <!-- 所有URI的后缀. -->
    <property name="suffix" value=".jsp"></property>
</bean>

<!-- 配置视图  BeanNameViewResolver 解析器: 使用视图的名字来解析视图 -->
<!-- 通过 order 属性来定义视图解析器的优先级, order 值越小优先级越高 -->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
    <property name="order" value="100"></property>
</bean>

5. 测试转发

       一般情况下,控制器方法返回字符串类型的值会被当成逻辑视图名处理。

前台代码:

<a href="handleView/testViewAndViewResolver.action">测试转发</a>

 后台代码:

@RequestMapping("/handleView/testViewAndViewResolver.action")
public String testViewAndViewResolver(){
    System.out.println("【Forward】测试转发");
    return SUCCESS;
}

6. 测试重定向

      redirect:success.jsp:会完成一个到 success.jsp 的重定向的操作。

前台代码:

<a href="handleView/testRedirect.action">测试重定向</a>

 后台代码:

@RequestMapping("/handleView/testRedirect.action")
public String testRedirect(){
    System.out.println("【Redirect】测试重定向");
    return "redirect:/login.jsp";
}

6、组合使用视图解析器

       如上述SpringMVC配置文件中的配置,将InternalResourceViewResolver视图解析器和BeanNameViewResolver视图解析器配合使用,视图解析器默认优先级为Integer.MAX_VALUE,所以在上述配置中,BeanNameViewResolver的优先级更高,只有按名称找不到视图后,才会找JSP。

  自定义View:

@Component
public class HelloView implements View {

    @Override
    public String getContentType() {
        return "text/html";
    }

    @Override
    public void render(Map<String, ?> model, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        response.getWriter().print("hello view, time: " + new Date());
    }
}

  前台代码:

<a href="handleView/testView.action">测试配置视图解析器</a>

 后台控制器代码:

@RequestMapping("/handleView/testView.action")
public String testView(){
    System.out.println("【BeanNameViewResolver】测试配置视图解析器");
    return "helloView";
}

 测试结果如下图,可以发现,当BeanNameViewResolver可以按名称找到视图View时,就用BeanNameViewResolver来解析视图。

SpringMVC(七)_视图和视图解析器