1 概述
- 请求处理方法执行完成后,最终返回一个ModelAndView对象。对于那些返回String、View或ModelMap等类型的处理方法,SpringMVC也会在内部将它们装配成一个ModelAndView对象,它包含了逻辑名和模型对象的视图。
- SpringMVC借助视图解析器(ViewResolver)得到最终的视图对象(View),最终的视图可以是JSP、也可以是Excel或JFreeChart等各种表现层形式的视图。
- 对于最终究竟采用何种视图对象对模型数据进行渲染,解析器并不关心,解析器的工作重点聚焦在生产模型数据的工作上,从而实现MVC的充分解耦。
2 视图
- 视图的作用是渲染模型数据,将模型的数据以某种形式呈现给客户。
- 为了实现视图模型和具体实现技术的解耦,Spring在org.springframework.web.servlet包中定义了一个高度抽象的View接口。
package org.springframework.web.servlet; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; public interface View { String RESPONSE_STATUS_ATTRIBUTE = View.class.getName() + ".responseStatus"; String PATH_VARIABLES = View.class.getName() + ".pathVariables"; String SELECTED_CONTENT_TYPE = View.class.getName() + ".selectedContentType"; @Nullable default String getContentType() { return null; } void render(@Nullable Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception; }
- 视图对象由视图解析器负责实例化。由于视图是无状态的,所以它们没有线程安全的问题。
3 视图解析器
- SpringMVC为逻辑视图名的解析提供了不同的策略,可以在Spring WEB上下文配置一种或多种解析策略,并指定他们之间的先后顺序。每一种映射策略对应一个具体的视图解析器实现类。
- 视图解析器的作用比较单一:将逻辑视图解析为一个具体的视图对象。
- 所有的视图解析器都必须实现ViewResolver接口:
- 程序员可以选择一个视图解析器或混用多个视图解析器。
- 每个视图都实现了Ordered接口并开放出了一个order属性,可以通过order属性指定解析器的优先顺序,order越小优先级越高。
- SpringMVC会按视图解析器顺序对逻辑视图进行解析,直到解析成功并返回视图对象,否则会抛出ServletException异常。
4 InternalResourceViewResolver
- 如果项目中使用了JSTL,则SpringMVC会自动把视图由InternalResourceView转变为JstlView。
- 如果使用了JSTL的fmt标签,则需要在SpringMVC的配置文件配置国际化资源文件。
<!-- 配置国际化 --> <bean class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="i18n"/> </bean>
- 如果希望直接响应通过SpringMVC渲染的页面(即不通过Controller跳转),可以使用<mvc:view-controller>标签。
<mvc:view-controller path="/login" view-name="login"/>
5 关于重定向
- 一般情况下,控制器方法返回字符串类型的值会被当成逻辑视图名处理。
- 如果返回的字符串中带forward:或redirect:前缀时,SpringMVC会把它们进行特殊处理,将forward:和redirect:当成指示符,其后的字符串作为URL来处理。
6 处理静态资源
- 优雅的REST风格的资源URL不希望带有.html或.do等后缀。
- 如果将DispatchserServlet的请求映射配置为/,则SpringMVC将捕获web容器的所有请求,包括静态资源的请求,springMVC会将它们当成一个普通请求来处理,因此会找不到对应的控制器将导致报错。
- 可以在SpringMVC的配置文件中配置<mvc:default-servlet-handler/>的方式解决静态资源问题。
- <mvc:default-servlet-handler/>将在SpringMVC的上下文中定义一个DefaultServletHttpRequestHandler,它会对进入DispatcherServlet的请求进行筛选,如果发现是没有经过映射的请求,就将该请求交由WEB应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理。
- 一般WEB应用服务器默认的Servlet的名称都是default。如果使用的WEB服务器的默认Servlet的名称不是default,则需要通过<mvc:default-servlet-name>的属性显示指定。