JSR 303(Bean Validation )

说明:

  在任何时候,当你要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情。应用程序必须通过某种手段来确保输入进来的数据从语义上来讲是正确的。

  在通常的情况下,应用程序是分层的,不同的层由不同的开发人员来完成。很多时候同样的数据验证逻辑会出现在不同的层,这样就会导致代码冗余和一些管理的问题,比如说语义的一致性等。为了避免这样的情况发生,最好是将验证逻辑与相应的域模型进行绑定。

  Bean Validation 为 JavaBean 验证定义了相应的元数据模型和 API。默认的元数据是 Java Annotations,也可以通过使用 XML 可以对原有的元数据信息进行覆盖和扩展。在应用程序中,通过使用 Bean Validation 或是你自己定义的 constraint(约束/限制),例如 @NotNull, @Max, @ZipCode, 就可以确保数据模型(JavaBean)的正确性。constraint 可以附加到字段,getter 方法,类或者接口上面。对于一些特定的需求,用户可以很容易的开发定制化的 constraint。Bean Validation 是一个运行时的数据验证框架,在验证之后验证的错误信息会被马上返回。

说明:

  下载 JSR 303 – Bean Validation 规范 http://jcp.org/en/jsr/detail?id=303
  Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate
Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的
constraint。如果想了解更多有关 Hibernate Validator 的信息,请查看 http://www.hibernate.org/subprojects/validator.html

Bean Validation 中的 constraint

表 1. Bean Validation 中内置的 constraint

Constraint 详细信息
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式

表 2. Hibernate Validator 附加的 constraint

Constraint 详细信息
@Email 被注释的元素必须是电子邮箱地址
@Length 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range 被注释的元素必须在合适的范围内

在IDEA中使用JSR 303

加入Jar包

  

  说明:切记要同时拷贝入在Tomcat的lib目录中。

在要验证的的JavaBean中加入约束条件

package domain;

import javax.validation.constraints.Past;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Date; /**
* Created by zy on 17-2-28.
*/
public class Product implements Serializable {
//实现了这个接口,可以安全的将数据保存到HttpSession中
private static final long serialVersionUID= 748392348L;
/**
* 序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,则反序列化将会导致 InvalidClassException。可序列化类可以通过声明名为 "serialVersionUID" 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)显式声明其自己的 serialVersionUID:
*/
private long id;
//被注释的元素的大小必须在指定的范围内
@Size(min = ,max = ,message="不能超过十个字符")
private String name; private String description;
private String price;
//被注释的元素必须是一个过去的日期
@Past
private Date productionDate; public Date getProductionDate() {
return productionDate;
} public void setProductionDate(Date productionDate) {
this.productionDate = productionDate;
} public long getId() {
return id;
} public void setId(long id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getDescription() {
return description;
} public void setDescription(String description) {
this.description = description;
} public String getPrice() {
return price;
} public void setPrice(String price) {
this.price = price;
} public String toString() {
return "Product{" +
"id=" + id +
", name='" + name + '\'' +
", description='" + description + '\'' +
", price='" + price + '\'' +
", productionDate=" + productionDate +
'}';
}
}

在要进行验证的控制器参数前加上@Valid

@RequestMapping(value = "/product_save",method = RequestMethod.POST)
public String saveProduct(@Valid @ModelAttribute Product product, BindingResult bindingResult,Model model)
{
logger.info("saveProduct called");
if(bindingResult.hasErrors())
{
List<ObjectError>objectErrors=bindingResult.getAllErrors();
Iterator<ObjectError> it =objectErrors.iterator();
while (it.hasNext())
{ System.out.println(it.next().toString());
}
//FieldError fieldError = bindingResult.getFieldError();
//logger.info("code:"+fieldError.getCode()+",object:"+fieldError.getObjectName()+",field:"+fieldError.getField());
product.setProductionDate(null);
model.addAttribute("product",product);
return "ProductForm";
}
model.addAttribute("product",product);
return "ProductForm";
}

其他:调用转换器,来规范日期时间

1.编译转换器

package converter;

import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; public class MyConverter implements Converter<String,Date> {
//<源类型,目标类型>
private String dataPattern;
public MyConverter(String dataPattern)
{
this.dataPattern=dataPattern;
System.out.println("DataPattern is"+dataPattern);
}
public Date convert(String s) {
try {
SimpleDateFormat simpleDateFormat= new SimpleDateFormat(dataPattern);
simpleDateFormat.setLenient(false);
//设置日期/时间的解析是否不严格,为false表示严格 return simpleDateFormat.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}

2.在SpringMVC的xml文件中配置转换器

<!--【注册转换器】-->
<mvc:annotation-driven conversion-service="conversionService"/>
<!--【配置转换器】-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="converter.MyConverter">
<constructor-arg type="java.lang.String" value="MM-dd-yyyy"/>
</bean>
</list>
</property>
</bean>

测试应用

输入错误表单信息:

  

控制台显示错误日志:

Field error in object 'product' on field 'name': rejected value [我就是要超过十个字符啊]; codes [Size.product.name,Size.name,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [product.name,name]; arguments []; default message [name],10,1]; default message [不能超过十个字符]
Field error in object 'product' on field 'productionDate': rejected value [Sat Dec 23 00:00:00 CST 2017]; codes [Past.product.productionDate,Past.productionDate,Past.java.util.Date,Past]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [product.productionDate,productionDate]; arguments []; default message [productionDate]]; default message [需要是一个过去的时间]

SpringMVC:学习笔记(7)——验证器(JSR303)的更多相关文章

  1. SpringMVC学习笔记九:拦截器及拦截器的简单实用

    SpringMVC中的interceptor拦截器是非常重要的,它的主要作用就是拦截指定的用户请求,并进行相应的预处理和后处理. 拦截时间点在"处理器映射器根据用户提交的请求映射出所要执行的 ...

  2. SpringMVC 学习笔记(六)拦截器

    5.1.处理器拦截器简介 Spring Web MVC的处理器拦截器(如无特殊说明,下文所说的拦截器即处理器拦截器) 类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理. ...

  3. SpringMVC 学习笔记(处理器映射器的配置)

    前端控制器(dispatchServlet) 在web.xml中配置前端控制器,在服务器启动时就被创建,用来对请求和响应进行接收 和 分发处理,其在配置时可以设置一个初始化参数,用来定位SpringM ...

  4. SpringMVC学习笔记:拦截器和过滤器

    首先说明一下二者的区别: 1. 拦截器基于java的反射机制,而过滤器是基于函数回调 2. 拦截器不依赖于servlet容器,过滤器依赖servlet容器 3. 拦截器只能对action请求起作用,而 ...

  5. 史上最全的SpringMVC学习笔记

    SpringMVC学习笔记---- 一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于Spring ...

  6. springmvc学习笔记(简介及使用)

    springmvc学习笔记(简介及使用) 工作之余, 回顾了一下springmvc的相关内容, 这次也为后面复习什么的做个标记, 也希望能与大家交流学习, 通过回帖留言等方式表达自己的观点或学习心得. ...

  7. springmvc学习笔记(常用注解)

    springmvc学习笔记(常用注解) 1. @Controller @Controller注解用于表示一个类的实例是页面控制器(后面都将称为控制器). 使用@Controller注解定义的控制器有如 ...

  8. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  9. SpringMVC:学习笔记(8)——文件上传

    SpringMVC--文件上传 说明: 文件上传的途径 文件上传主要有两种方式: 1.使用Apache Commons FileUpload元件. 2.利用Servlet3.0及其更高版本的内置支持. ...

随机推荐

  1. js中级四: 跨域

    原文链接:http://www.cnblogs.com/scottckt/archive/2011/11/12/2246531.html 什么是跨域? 首先什么是跨域,简单地理解就是因为JavaScr ...

  2. LeetCode532. K-diff Pairs in an Array

    Description Given an array of integers and an integer k, you need to find the number of unique k-dif ...

  3. figure margins too large错误解决

    使用Rstudio,遇到下面这个错误: figure margins too large 这是因为界面右下角的“plot”窗口太小,显示不了,将右下角的窗口调大就能解决

  4. Linux 总结2

    cd                                             pwd                                            mkdir ...

  5. Sping 的 BeanFactory 容器

    Sping 的 BeanFactory 容器 这是一个最简单的容器,它主要的功能是为依赖注入 (DI) 提供支持,这个容器接口在 org.springframework.beans.factory.B ...

  6. POI Excel 冷冻线

    冷冻线 Sheet.createFreezePane data bar and  color scale SheetConditionalFormatting scf = sheet.getSheet ...

  7. CentOS6.X 升级内核至 3.10

    1.1 查看当前版本 [root@localhost ~]# uname -r -.el6.x86_64 1.2 导入public key [root@localhost ~]# rpm --impo ...

  8. 简单的c语言小程序 回光返照

    主函数 int main(int argc,char * argv[]) -- arg代表英文的参数缩写 c代表count计数 argc { return 0;  -- 0返还给系统,代表程序正确运行 ...

  9. mysqldump: Got error: 1045

    问题:最近备份mysql然后在执行mysqldump的时候提示权限和密码有问题 报错: Warning: Using a password on the command line interface ...

  10. 【BZOJ2730】[HNOI2012]矿场搭建 Tarjan

    [BZOJ2730][HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处. ...