本文主要讲解一下SpringMVC视图相关也比较常用的知识点。视图解析器的作用也比较单一,就是将一个逻辑视图解析为一个具体的逻辑对象。
从以下几个方面展开讲解:SpringMVC视图解析的流程,JstlView和fmt标签实现国际化,mvc:view- controller 标签,自定义视图,重定向。
1、SpringMVC视图解析的流程
作为初学者,使用SpringMVC框架时,控制器的的目标方法主要使用返回字符串的形式来访问视图资源。其实,SpringMVC还支持返回值是View对象或者ModelAndView对象。但是,无论是什么类型,SpringMVC都会将它装配为ModelAndView类型。SpringMVC 借助视图解析器(ViewResolver)得到最终的视图对象(View),最终的视图可以是 JSP ,也可能是 Excel、JFreeChart等各种表现形式的视图。对于最终究竟采取何种视图对象对模型数据进行渲染,控制器并不关心,控制器工作重点聚焦在生产模型数据的工作上,从而实现 MVC 的充分解耦。
我们发现一个有趣的命名法则,就拿视图解析器InternalResourceViewResolver来说,作为ViewResolver的实现类来说(事实上任何一个视图解析器都应该实现ViewResolver接口),InternalResource主要代表的是JSP类视图资源,ViewResolver则指明这是一个视图解析器,所以看名字就可以看出视图解析器可以渲染的视图资源有哪些。下面就是视图和视图处理器大致的总览。
视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给客户。为了实现视图模型和具体实现技术的解耦,Spring 在 org.springframework.web.servlet 包中定义了一个高度抽象的 View 接口
视图对象由视图解析器负责实例化。由于视图是无状态的,所以他们不会有线程安全的问题。
2、JstlView和fmt标签实现国际化
如果项目中使用了JSTL,SpringMVC会把视图由默认的InternalResource转换为JstlView。如果在项目中配置了国际化资源文件,就可以使用JSTL的fmt标签实现国际化。
先来看看国际化资源文件
user.properties
username=username
password=password
user_zh_CN.properties
username=用户名
password=密码
user_en_US.properties
username=username
password=password
然后是ftm标签的使用
...
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
...
<fmt:message key="username"></fmt:message>
<fmt:message key="password"></fmt:message>
...
如此便可以实现国际化
3、mvc:view- controller 标签
若希望直接响应通过 SpringMVC 渲染的页面,可以使用 mvc:view- controller 标签实现。但是配置了这个标签以后,会导致其他的正常的经过控制器转发到这个视图出现异常。所以我们可以继续配置一个mvc:annotation-driven标签。至于为什么这样加以后的文章再讲。具体配置如下。
<!-- 配置直接转发的页面 -->
<!-- 可以直接响应通过SpringMVC渲染的界面,而无需经过handler -->
<mvc:view-controller path="/success" view-name="success"/>
<!-- 实际的项目开发中通常都需要配置mvc:annotation-driven标签 -->
<mvc:annotation-driven></mvc:annotation-driven>
4、自定义视图
为了实现视图模型和具体实现技术的解耦,Spring 在 org.springframework.web.servlet 包中定义了一个高度抽象的 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().write("hello view,time:"+new Date());
}
}
注意我们需要将上面的视图类作为组件注册到Spring容器,这个Bean的id是默认的,即类名的首字母小写的字符串。实际上,SpringMVC 为逻辑视图名的解析提供了不同的策略,可 以在 Spring WEB 上下文中配置一种或多种解析策略,并 指定他们之间的先后顺序。每一种映射策略对应一个具体 的视图解析器实现类。然后可以通过order 属性指定解析器的优先顺序,order越小优先级越高。
通过分析视图解析的流程我们知道,SpringMVC会使用所有的视图解析器解析ModelAndView,直到成功为止,所以我们应该把不经常用到的视图解析器放在前面使用,最稳定的最常用的应该放在后面。SpringMVC默认InternalResourceViewResolver视图解析器order值最大。我们看如下配置:
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 配置BeanNameViewResolver视图解析器
这个视图解析器的作用是直接按照视图的名字来解析视图,比如HelloView类对应的视图就是helloView
<!-- 使用order属性设置此视图解析器的优先级,也就是说BeanNameViewResolver比InternalResourceViewResolver的优先级高
此视图解析器无法使用再使用InternalResourceViewResolver -->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="100"></property>
</bean>
访问这个视图的测试方法
@RequestMapping("/testView")
public String testView(){
System.out.println("HelloView");
return "helloView";
}
5、重定向
一般情况下,控制器方法返回字符串类型的值会被当成逻 辑视图名处理,如果返回的字符串中带 forward: 或 redirect: 前缀时,SpringMVC 会对他们进行特殊处理:将 forward: 和 redirect: 当成指示符,其后的字符串作为 URL 来处理。例如:redirect:success:会完成一个到 success.jsp 的重定向的操作;forward:success:会完成一个到 success.jsp 的转发操作。
其他相关知识点还有很多,以后如果项目用到或者随着学习的深入,我会回来补充的。