Spring学习笔记-springMVC校验框架
2015-08-08 12:41
435 查看
输入校验是Web开发最重要的任务之一。SpringMVC作为当今最流行的MVC框架,自然也对输入校验做了很好的支持。
在SpringMVC中可以用两种方式来进行输入校验
1)利用SpringMVC自带的校验框架
2)利用JSR 303
下面我们对着两种校验方式做详细的描述。
Spring验证框架
spring的验证框架入口为
Spring在完成校验动作时,首先会调用supoorts()方法,判断当前的object在不在校验队列中,如果在,则紧接着调用validate方法,进行校验。
在应用校验框架是,我们最常用的可能就是Errors接口了,这个接口有一些实现类,我们可以吧它理解为一个存放错误信息的容器,里面存放着一系列的域错误(FieldError)和对象错误(ObjectError),同时,它还提供了获取错误信息和加入错误信息的方法,例如:
利用这些方法,我们就可以在这个“错误容器”里方便的存取错误数据。
在进行数据校验时,我们以往经常要写很多向下面这样 代码:
或者
这样的代码虽然是必须的,但是大量的重复往往令人头疼,幸好,Spring为我们提供了一个工具类,可以很好的解决上面的问题,
该工具类还保护很多重载方法,大家可以自己查看API文档。
看起来也是蛮强大的吧……
下面,我们就用一个简单是范例,来说明一下Spring校验框架的基本用法。
1)首先,创建一个POJO类
2)编写一个实现了Validator接口的校验器
3)创建一个用于显示错误信息的资源文件(.properties)
4)紧接着,要把这个资源文件注册到spring环境中,这样在检验器中才能得到具体的错误提示。
5)最后,要编写一个应用了校验器的Controller来完成校验任务。
完成。
利用JSR 303进行校验。
首先要说明的是,JSR是一系列的规范,它本身并没有使用意义,如果想在JSR规范的基础上完成校验,则需要导入它的实现。目前JSR303的实现有两种:Hibernate Validator 和 Apache BVal。
下面先说明一下JSR 303的规范。
利用这些注解直接表述bean中的域就可以方便的实现校验。
下面我们还是通过一个小例子,来看一下它的具体用法。
1)创建JavaBean,利用JSR注解标注
2)创建Controller,不用实现校验器了哦!这是重点。
3)配置一个资源文件,用于提示信息的显示。
4)再像上面的那样,注册资源文件到spring容器。
哦了,搞定,就这么用。
在SpringMVC中可以用两种方式来进行输入校验
1)利用SpringMVC自带的校验框架
2)利用JSR 303
下面我们对着两种校验方式做详细的描述。
Spring验证框架
spring的验证框架入口为
Validator接口,该接口的签名是这样的:
public interface Validator { boolean supports(Class<?> clazz); void validate(Object target, Errors errors); }
Spring在完成校验动作时,首先会调用supoorts()方法,判断当前的object在不在校验队列中,如果在,则紧接着调用validate方法,进行校验。
在应用校验框架是,我们最常用的可能就是Errors接口了,这个接口有一些实现类,我们可以吧它理解为一个存放错误信息的容器,里面存放着一系列的域错误(FieldError)和对象错误(ObjectError),同时,它还提供了获取错误信息和加入错误信息的方法,例如:
void reject(String errorCode, Object[] errorArgs, String defaultMessage); void rejectValue(String field, String errorCode, Object[] errorArgs, String defaultMessage); boolean hasFieldErrors(); List<FieldError> getFieldErrors(); List<ObjectError> getAllErrors(); ......
利用这些方法,我们就可以在这个“错误容器”里方便的存取错误数据。
在进行数据校验时,我们以往经常要写很多向下面这样 代码:
if(firstName == null && firstName.isEmpty()) errors.rejectValue("price");
或者
if(firstName == null || firstName.trim().isEmpty()) errors.rejectValue("price");
这样的代码虽然是必须的,但是大量的重复往往令人头疼,幸好,Spring为我们提供了一个工具类,可以很好的解决上面的问题,
ValidtionUtils,利用这个工具类就可以吧具有上面功能 代码写的很优雅:
ValidationUtils.rejectIfEmpty("price"); ValidationUtils.rejectIfEmptyOrWhitespace("price");
该工具类还保护很多重载方法,大家可以自己查看API文档。
看起来也是蛮强大的吧……
下面,我们就用一个简单是范例,来说明一下Spring校验框架的基本用法。
1)首先,创建一个POJO类
@SuppressWarnings("serial") public class Product implements Serializable{ private String name; private String description; private Float price; private Date productionDate; setter/getter.... }
2)编写一个实现了Validator接口的校验器
public class ProductValidator implements Validator{ Logger logger = Logger.getLogger(ProductValidator.class); //spring通过调用该方法确定是否对某个对象进行校验(validate(target,errors)) @Override public boolean supports(Class<?> clazz) { //验证类型是否一样 return Product.class.isAssignableFrom(clazz); } @Override public void validate(Object target, Errors errors) { Product product = (Product)target; //强转对象类型 //校验开始 ValidationUtils.rejectIfEmpty( //验证null 和 "" 空字符串 errors, "name", //域名称 "productname.required" //错误编码 ); ValidationUtils.rejectIfEmpty( errors, "price", "price.required" ); ValidationUtils.rejectIfEmpty(errors, "productionDate", "productionDate.required"); //手动向errors中添加错信息的示例 Float price = product.getPrice(); if(price != null && price < 0){ errors.rejectValue("price", "price.negative");} Date productionDate = product.getProductionDate(); if(productionDate != null){ //与当前时间比较,如果在当前时间后,则判定错误 if(productionDate.after(new Date())){ logger.info(" productDate error"); errors.rejectValue("productionDate", "productiondate.invalid"); } } } }
3)创建一个用于显示错误信息的资源文件(.properties)
productname.required.product.name=Please enter a product name price.required=Please enter a price productiondate.required=Please enter a production date productiondate.invalid=Invalid production date. Please ensure the production date is not later than today
4)紧接着,要把这个资源文件注册到spring环境中,这样在检验器中才能得到具体的错误提示。
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="/WEB-INF/resource/messages"></property> </bean>
5)最后,要编写一个应用了校验器的Controller来完成校验任务。
/** * @Description: 校验框架测试 controller. * @Author:Zander * @CreateDate:Aug 8, 2015 * @Company: */ @Controller public class ProductController { private static final Logger logger = Logger.getLogger(ProductController.class); @RequestMapping(value="/product_input") public String inutProduct(Model model){ model.addAttribute("product", new Product()); return "productionForm"; } public String saveProduct(@ModelAttribute Product product, BindingResult bindingResult, Model model){ ProductValidator productValidator = new ProductValidator(); productValidator.validate(product, bindingResult); //调用校验器 //校验未通过 if(bindingResult.hasErrors()){ //得到校验是写入的错误信息 FieldError fieldError = bindingResult.getFieldError(); logger.info("Code:" + fieldError.getCode() + ", field:" + fieldError.getField()); //返回表单视图 return "productForm"; } //校验通过 model.addAttribute("product", product); return "productDetails"; } }
完成。
利用JSR 303进行校验。
首先要说明的是,JSR是一系列的规范,它本身并没有使用意义,如果想在JSR规范的基础上完成校验,则需要导入它的实现。目前JSR303的实现有两种:Hibernate Validator 和 Apache BVal。
下面先说明一下JSR 303的规范。
@AssertFalse 应用于boolean属性,该属性值必须为False @AssertFalse boolean hasChildern @AssertTrue 应用于boolean属性,该属性值必须为True @AssertTrue boolean isEmpty @DecimalMax 该属性必须为小于或等于指定的小树 @DecimalMax("1.1") BigDecimal price @DecimalMin 该属性必须大于或等于指定值的小数 @DecimalMin("0.04") @Digits 该属性必须在指定的范围内 @Digits(integer=5,fraction=2) BigDecimal price; @Future 该属性值必须是未来的一个日期 @Future Date shippingDate @Max 该属性值必须是一个小于或等于指定数值的整数 @Max(150) int age @Min 该属性值必须是一个大于或等于指定数值的整数 @Min(150) int age @NotNull String firstName @Null 该值必须为null @Null String testString @Past 该值必须为过去的一个时间 @Past Date birthDate @Pattern 该属性hi必须与指定的常规表达式匹配 @Pattern(regext="\\d{3}") @Size 该属性值必须在制定范围内 @Size(min=2,max=140) String description
利用这些注解直接表述bean中的域就可以方便的实现校验。
下面我们还是通过一个小例子,来看一下它的具体用法。
1)创建JavaBean,利用JSR注解标注
/** * @Description: JSR校验 * @Author:Zander * @CreateDate:Aug 8, 2015 * @Company: */ public class Product2 { @Size(min=1,max=10) private String name; private String description; private Float price; @Past private Date productionDate; geter()/setter() ... }
2)创建Controller,不用实现校验器了哦!这是重点。
/** * @Description: JSR 校验测试Controller. * @Author:Zander * @CreateDate:Aug 8, 2015 * @Company: */ @Controller public class ProductController2 { private static final Logger logger = Logger.getLogger(ProductController2.class); public String inutProduct(Model model){ model.addAttribute("product", new Product2()); return "productForm"; } public String saveProduct(@Valid @ModelAttribute Product2 product2, BindingResult bingBindingResult, Model model){ //判断是否通过校验 此处利用@Valid 注解 加上 JSR注解 就不用显示的创建校验器 if(bingBindingResult.hasErrors()){ FieldError fieldError = bingBindingResult.getFieldError(); logger.info("Code:" + fieldError.getCode() + ", object:" + fieldError.getObjectName() + ", field : " + fieldError.getField()); return "productForm"; } //save product model.addAttribute("product", product2); return "productDetails"; } }
3)配置一个资源文件,用于提示信息的显示。
Size.product.name=Product name mast be 1 to 10 characters long Past.product.productionDate=Production date must a past time
4)再像上面的那样,注册资源文件到spring容器。
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="/WEB-INF/resource/messages"></property> </bean>
哦了,搞定,就这么用。
相关文章推荐
- 什么是类的反射?怎么使用类的反射?
- Java Servlet 技术简介
- 使用snap ci+GitHub将一个Java Web项目部署到Heroku
- Java环境变量配置
- 使用递归方式写的走迷宫算法(Java)
- Java_逃逸分析技术
- Spring Boot和JPA开发的一些坑
- struts & 运行机制
- Java并发编程之ConcurrentHashMap原理分析
- Spring3 MVC 深入研究
- Defining a controller with @Controller
- [笔记][Java7并发编程实战手册]2.2使用syncronized实现同步方法
- 配置struts2不当错误
- java 去掉html标签
- Setting property 'source' to 'org.eclipse.jst.jee.server:jeecg' did not find a matching property
- Implementing Controllers
- JAVA实现EXCEL公式专题(一)——EXCEL公式分类与解析步骤
- java怎么用一行代码初始化ArrayList
- java项目导出为一个可执行文件jar包
- java中j=J++综合理解