前言
本博文主要讲解的知识点如下:
- 校验器
- 统一处理异常
- RESTful
- 拦截器
Validation
在我们的Struts2中,我们是继承ActionSupport来实现校验的…它有两种方式来实现校验的功能
- 手写代码
- XML配置
- 这两种方式也是可以特定处理方法或者整个Action的
而SpringMVC使用JSR-303(javaEE6规范的一部分)校验规范,springmvc使用的是Hibernate Validator(和Hibernate的ORM无关)
快速入门
导入jar包
这里写图片描述
配置校验器
<!-- 校验器 --> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <!-- 校验器 --> <property name="providerClass" value="org.hibernate.validator.HibernateValidator" /> <!-- 指定校验使用的资源文件,如果不指定则默认使用classpath下的ValidationMessages.properties --> <property name="validationMessageSource" ref="messageSource" /> </bean>
错误信息的校验文件配置
<!-- 校验错误信息配置文件 --> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <!-- 资源文件名 --> <property name="basenames"> <list> <value>classpath:CustomValidationMessages</value> </list> </property> <!-- 资源文件编码格式 --> <property name="fileEncodings" value="utf-8" /> <!-- 对资源文件内容缓存时间,单位秒 --> <property name="cacheSeconds" value="120" /> </bean>
添加到自定义参数绑定的WebBindingInitializer中
<!-- 自定义webBinder --> <bean id="customBinder" class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> <!-- 配置validator --> <property name="validator" ref="validator" /> </bean>
最终添加到适配器中
<!-- 注解适配器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <!-- 在webBindingInitializer中注入自定义属性编辑器、自定义转换器 --> <property name="webBindingInitializer" ref="customBinder"></property> </bean>
创建CustomValidationMessages配置文件
这里写图片描述
定义规则
package entity; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import java.util.Date; public class Items { private Integer id; //商品名称的长度请限制在1到30个字符 @Size(min=1,max=30,message="{items.name.length.error}") private String name; private Float price; private String pic; //请输入商品生产日期 @NotNull(message="{items.createtime.is.notnull}") private Date createtime; private String detail; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name == null ? null : name.trim(); } public Float getPrice() { return price; } public void setPrice(Float price) { this.price = price; } public String getPic() { return pic; } public void setPic(String pic) { this.pic = pic == null ? null : pic.trim(); } public Date getCreatetime() { return createtime; } public void setCreatetime(Date createtime) { this.createtime = createtime; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail == null ? null : detail.trim(); } }
测试:
<%-- Created by IntelliJ IDEA. User: ozc Date: 2017/8/11 Time: 9:56 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>测试文件上传</title> </head> <body> <form action="${pageContext.request.contextPath}/validation.action" method="post" > 名称:<input type="text" name="name"> 日期:<input type="text" name="createtime"> <input type="submit" value="submit"> </form> </body> </html>
Controller需要在校验的参数上添加@Validation注解…拿到BindingResult对象…
@RequestMapping("/validation") public void validation(@Validated Items items, BindingResult bindingResult) { List<ObjectError> allErrors = bindingResult.getAllErrors(); for (ObjectError allError : allErrors) { System.out.println(allError.getDefaultMessage()); } }
由于我在测试的时候,已经把日期转换器关掉了,因此提示了字符串不能转换成日期,但是名称的校验已经是出来了…
这里写图片描述
分组校验
分组校验其实就是为了我们的校验更加灵活,有的时候,我们并不需要把我们当前配置的属性都进行校验,而需要的是当前的方法仅仅校验某些的属性。那么此时,我们就可以用到分组校验了…
步骤:
- 定义分组的接口【主要是标识】
- 定于校验规则属于哪一各组
- 在Controller方法中定义使用校验分组
这里写图片描述
这里写图片描述
这里写图片描述
统一异常处理
在我们之前SSH,使用Struts2的时候也配置过统一处理异常…
当时候是这么干的:
- 在service层中自定义异常
- 在action层也自定义异常
- 对于Dao层的异常我们先不管【因为我们管不着,dao层的异常太致命了】
- service层抛出异常,Action把service层的异常接住,通过service抛出的异常来判断是否让请求通过
- 如果不通过,那么接着抛出Action异常
- 在Struts的配置文件中定义全局视图,页面显示错误信息
详情可看:http://blog.csdn.net/hon_3y/article/details/72772559
那么我们这次的统一处理异常的方案是什么呢????
我们知道Java中的异常可以分为两类
- 编译时期异常
- 运行期异常
对于运行期异常我们是无法掌控的,只能通过代码质量、在系统测试时详细测试等排除运行时异常
而对于编译时期的异常,我们可以在代码手动处理异常可以try/catch捕获,可以向上抛出。
我们可以换个思路,自定义一个模块化的异常信息,比如:商品类别的异常
public class CustomException extends Exception { //异常信息 private String message; public CustomException(String message){ super(message); this.message = message; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
我们在查看Spring源码的时候发现:前端控制器DispatcherServlet在进行HandlerMapping、调用HandlerAdapter执行Handler过程中,如果遇到异常,在系统中自定义统一的异常处理器,写系统自己的异常处理代码。。
这里写图片描述
这里写图片描述
我们也可以学着点,定义一个统一的处理器类来处理异常…