1.理解SpringMVC视图解析
上一篇讲到SpringMVC执行流程,DispatcherServlet会将模型和视图名交给视图解析器来解析生成响应视图

Spring MVC定义了一个名为ViewResolver的接口,它大致如下所示:
1 | public interface ViewResolver{ |
当给resolveViewName()方法传入一个视图名和Locale对象时,
它会返回一个View实例。View是另外一个接口,如下所示:
Locale对象,以便于恰当地格式化地域
相关的值,如日期和货币。信息标签可以借助Spring的信息资源和
Locale,从而选择适当的信息渲染到HTML之中。通例如:JSTL能够获得Locale对象以及Spring中配置的信息资源
1 | public interface View{ |
View接口的任务就是接受模型以及Servlet的request和response对象,
并将输出结果渲染到response中。
我们只需实现这两个接口就可以解析视图了,不过Spring自带了13个视图解析器,能够将逻辑视图名转换为物理实现。
| 视图解析器 | 描述 |
|---|---|
| BeanNameViewResolver | 将视图解析为Spring应用上下文中的bean,其中bean的ID与视图的名字相同 |
| ContentNegotiatingViewResolver | 通过考虑客户端需要的内容类型来解析视图,委托给另外一个能够产生对应内容类型的视图解析器 |
| FreeMarkerViewResolver | 将视图解析为FreeMarker模板 |
| InternalResourceViewResolver | 将视图解析为Web应用的内部资源(一般为JSP) |
| JasperReportsViewResolver | 将视图解析为JasperReports定义 |
| ResourceBundleViewResolver | 将视图解析为资源bundle(一般为属性文件) |
| TilesViewResolver | 将视图解析为Apache Tile定义,其中tile ID与视图名称相同。注意有两个不同的TilesViewResolver实现,分别对应于Tiles 2.0和Tiles 3.0 |
| UrlBasedViewResolver | 直接根据视图的名称解析视图,视图的名称会匹配一个物理视图的定义 |
| VelocityLayoutViewResolver | 将视图解析为Velocity布局,从不同的Velocity模板中组合页面 |
| VelocityViewResolver | 将视图解析为Velocity模板 |
| XmlViewResolver | 将视图解析为特定XML文件中的bean定义。类似于BeanName-ViewResolver |
| XsltViewResolver | 将视图解析为XSLT转换后的结果 |
我们常用的也就那么几个,InternalResourceViewResolver一般会
用于JSP,TilesViewResolver用于Apache Tiles视图(布局),而FreeMarkerViewResolver和VelocityViewResolver分别
对应FreeMarker和Velocity模板视图
2.配置JSP视图解析器
InternalResourceViewResolver会将视图名解析为JSP文件。另外,如果在你的JSP页面中使用了JSP标准标签库(JavaServer Pages Standard Tag Library,JSTL)的话,InternalResourceViewResolver能够将视图名解析为JstlView形式的JSP文件,从而将JSTL本地化和资源bundle变量暴露给JSTL的格式化(formatting)和信息(message)标签
1 |
|
当然如果喜欢xml配置方式也可以用xml配置,我个人喜欢JavaConf方式
支持JSTL
如果想让InternalResourceViewResolver将视图解析为JstlView,而不是InternalResourceView的话,
那么我们只需设置它的viewClass属性即可:1
2
3
4
5
6
7
8
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(org.springframework.web.servlet.view.JstlView.class)
return resolver;
}
3.表单校验
大多数项目都会有表单的提交,比如注册、登录等,我们通常会在前台通过JS对用户的输入进行校验,也可后台进行数据校验,
前台校验的优点是不用发送请求,速度快,缺点是不安全,前端校验可以被轻易的绕开。后端的校验恰好相反。
平时我们大多会在两端都进行校验,前端初步校验提高用户友好性,后端校验提高安全性。
下面我们谈谈后端的校验。
最简单粗暴的方法是在后端获取参数后逐个写逻辑判断。这种方式会让我们的Controller很乱很臃肿。与其让校验逻辑弄乱我们的处理器方法,还不如使用Spring对Java校验API(Java Validation API,又称JSR-303)的支持。从Spring 3.0开始,在Spring MVC中提供了对Java校验API的支持。在Spring MVC中要使用Java校验API的话,并不需要什么额外的配置。只要保证在类路径下包含这个Java API的实现即可,比如Hibernate Validator。Java校验API定义了多个注解,这些注解可以放到属性上,从而限制这些属性的值。所有的注解都位于javax.validation.constraints包中
以下是JAVA校验API提供的一些注解:
| 注解 | 描述 |
|---|---|
| @AssertFalse | 所注解的元素必须是Boolean类型,并且值为false |
| @AssertTrue | 所注解的元素必须是Boolean类型,并且值为true |
| @DecimalMax | 所注解的元素必须是数字,并且它的值要小于或等于给定的BigDecimalString值 |
| @DecimalMin | 所注解的元素必须是数字,并且它的值要大于或等于给定的BigDecimalString值 |
| @Digits | 所注解的元素必须是数字,并且它的值必须有指定的位数 |
| @Future | 所注解的元素的值必须是一个将来的日期 |
| @Max | 所注解的元素必须是数字,并且它的值要小于或等于给定的值 |
| @Min | 所注解的元素必须是数字,并且它的值要大于或等于给定的值 |
| @NotNull | 所注解元素的值必须不能为null |
| @Null | 所注解元素的值必须为null |
| @Past | 所注解的元素的值必须是一个已过去的日期 |
| @Pattern | 所注解的元素的值必须匹配给定的正则表达式 |
| @Size | 所注解的元素的值必须是String、集合或数组,并且它的长度要符合给定的范围 |
例如:
实体类:
1 | package spittr; |
Controller 方法
1 | (value="/register", method=POST) |
如果有校验出现错误的话,那么这些错误可以通过Errors对象进行访问,现在这个对象已作为processRegistration()方法的参数。(很重要一点需要注意,Errors参数要紧跟在带有@Valid注解的参数后面,@Valid注解所标注的就是要检验的参数。)processRegistration()方法所做的第一件事就是调用Errors.hasErrors()来检查是否有错误。
但这时候返回表单页面会丢失之前填的数据
4.使用Spring的JSP库
使用这个标签库可以将错误信息友好的显示在页面,也会保留验证钱的数据(解决上面的问题),当然也可以自己写处理,方式很多,不局限这一种
当为JSP添加功能时,标签库是一种很强大的方式,能够避免在脚本块中直接编写Java代码。Spring提供了两个JSP标签库,用来帮助定义Spring MVC Web的视图。其中一个标签库会用来渲染HTML表单标签,这些标签可以绑定model中的某个属性。另外一个标签库包含了一些工具类标签,我们随时都可以非常便利地使用它们。
具体使用方法请参考Spring in Action 6.2.2
5.使用Apache Tiles视图定义布局
到现在为止,我们很少关心应用中Web页面的布局问题。每个JSP完全负责定义自身的布局,在这方面其实这些JSP也没有做太多工作。假设我们想为应用中的所有页面定义一个通用的头部和底部。最原始的方式就是查找每个JSP模板,并为其添加头部和底部的HTML。但是这种方法的扩展性并不好,也难以维护。为每个页面添加这些元素会有一些初始成本,而后续的每次变更都会耗费类似的成本。更好的方式是使用布局引擎,如Apache Tiles,定义适用于所有页面的通用页面布局。Spring MVC以视图解析器的形式为Apache Tiles提供了支持,这个视图解析器能够将逻辑视图名解析为Tile定义。
来感受下:
1 | <?xml version="1.0" encoding="ISO-8859-1" ?> |
具体使用方法请参考Spring in Action 6.3