赞
踩
Java Specification Requests的缩写,意思是Java 规范提案。 是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。 任何人都可以提交JSR,以向Java平台增添新的API和服务。
是一个java规范(准确来说,属于JavaEE范围内的规范)。
主流实现框架,有Hibernate validation、Spring validation等。而Spring 的validation 核心模块,首先是完整实现BV规范,JSR380。其次,在spring-mvc中实现了自动化的校验。并且基于hibernate validation进行了增强(并兼容hibernate validation的实现)
在java的世界中,没有BV之前的校验,依靠一些第三方的工具包提供的基础简单的校验,或者自行编码验证。工具包主要有Apache的common工具包中的validationUtils、Spring的validationUtils。
例一:
public class StandardValidation { public static void main(String[] args) { System.out.println(validationWithoutAnnotation(" ", -1)); } public static String validationWithoutAnnotation(String inputString, Integer inputInt) { String error = null; if (null == inputString) { error = "inputString不能为null"; } else if (null == inputInt) { error = "inputInt不能为null"; } else if (1 > inputInt.compareTo(0)) { error = "inputInt必须大于0"; } else if (inputString.isEmpty() || inputString.trim().isEmpty()) { error = "inputString不能为空字符串"; } else { // DO } return error; } }
例二:
Spring的自行开发的数据校验功能由3个部分组成:
校验器——Validator,他会运行校验代码。
校验对象,实际上就是一个JavaBean,Validator会对其进行校验。
校验结果——Errors,一次校验的结果都存放在Errors实例中。
这是Spring在Bean Validation规范制定之前就实现的数据校验功能,ValidationUtils的注释中@since标签是2003年5月6号,而JSR-303定稿时间已经是6年之后(2009年)的事了。
package chkui.springcore.example.hybrid.springvalidation.entity;
//车辆信息
public class Vehicle {
private String name;
private String type;
private String engine;
private String manufacturer;
private Calendar productionDate;
/**Getter Setter*/
}
然后针对这个实体声明一个校验器。校验器要实现org.springframework.validation.Validator接口:
package chkui.springcore.example.hybrid.springvalidation.validator; public class VehicleValidator implements Validator { private List<String> _TYPE = Arrays.asList(new String[] { "CAR", "SUV", "MPV" }); public boolean supports(Class<?> clazz) { //将验证器和实体类进行绑定,如果这里返回false在验证过程中会抛出类型不匹配的异常 return Vehicle.class.isAssignableFrom(clazz); } public void validate(Object target, Errors errors) { //验证数据 Vehicle vehicle = Vehicle.class.cast(target); if (null == vehicle.getName()) { //使用验证工具绑定结果 ValidationUtils.rejectIfEmpty(errors, "name", "name.empty", "车辆名称为空"); } if (!_TYPE.contains(vehicle.getType())) { //向Error添加验证错误信息 <2> errors.rejectValue("type", "type.error", "汽车类型必须是" + _TYPE); } //More validate ...... } }
有了验证对象(JavaBean)和对应的验证器(Validator)就完成了一组验证功能。注意VehicleValidator::validate方法传递的errors参数,验证工具会将错误实例传递进来交给开发者去组装验证结果。
public class SpringValidationApp { private static void springValidation(ApplicationContext ctx) { VehicleValidator vehicleValidator = new VehicleValidator();//创建验证器 Vehicle vehicle = new Vehicle();//创建验证对象 <1> ValidationError error = new ValidationError("Vehicle");//创建错误信息 ValidationUtils.invokeValidator(vehicleValidator, vehicle, error);//执行验证 List<FieldError> list = error.getFieldErrors(); int count = 1; //输出验证结果 for(FieldError res : list) { print("Error Info ", count++ , "."); print("Entity:", res.getObjectName()); print("Field:", res.getField()); print("Code:", res.getCode()); print("Message:", res.getDefaultMessage()); print("-"); } } }
执行完毕后,ValidationError中记录了所有校验错误信息。错误信息分为4个部分:
验证的对象的名称:在执行验证器的代码中<1>部分创建错误对象时指定。Vehicle就是验证对象的名称。
错误的域、错误code和错误信息:每一个错误都有对应的域、错误编码以及错误信息,在验证器<2>位置的代码就是指定错误信息。
以上错误信息可以通过error.getFieldErrors();来获取。
使用后的代码对比:
public class Game {
@NotNull //非空
@Length(min=0, max=5) //字符串长度小于5,这个是一个Hibernate Validator增加的注解
private String name;
@NotNull
private String description;
@NotNull
@Min(0) //最小值>=0
@Max(10) //最大值<=10
private int currentVersion;
//getter and setter…………
}
1、更精简的代码
2、标准规范化的接口,使得学习、理解、交流沟通的成本大大地降低
3、代码的复用性更好
4、更加适合做统一的异常处理
5、依赖标准API规范,所以没有框架或者工具的强依赖性,可随意更换规范的实现框架
@size(min = 8,default.group.class)
@size(min = 12, admin.group.class)
private char[] password ……
private List<String> names;
@OneElements(constraint=@NotEmpty)
private List<String> names;
private List<@NotEmpty String> names;
private List<@Pattern(regexp="[a-zA-Z] * ") String> names;
……
本示例,提供的特性有:
统一异常处理
使用hibernate validation校验:
2.1:简单校验
2.2:分组校验
2.3:定制错误信息
2.4:自定义校验约束
2.5:使用定制化的校验消息等级提示信息
2.6:使用简单的组合约束
2.7:在方法上,使用对返回值的校验、参数的校验(契约式编程)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
/** * @NotNull://CharSequence, Collection, Map 和 Array 对象不能是 null, 但可以是空集(size = 0)。 * @NotEmpty://CharSequence, Collection, Map 和 Array 对象不能是 null 并且相关对象的 size 大于 0。 * @NotBlank://String 不是 null 且去除两端空白字符后的长度(trimmed length)大于 0。 */ public Integer id; @NotBlank(message = "用户名不能为空") @Length(min = 6,max = 20,message = "用户名需要为 6 - 20 个字符") public String username; @NotNull(message = "年龄不能为空") public Integer age; @Email(message = "邮箱格式不正确") @NotBlank(message = "邮箱不能为空") public String email; @NotBlank(message = "手机号码不能为空") public String phoneNumber;
@PostMapping("/addByJson")
@ResponseBody
public ResultBean addByJson(@RequestBody @Valid User user) {
userService.add(user);
return ResultBean.success();
}
https://github.com/nomemory/java-bean-validation-extension
https://github.com/hibernate/hibernate-demos/tree/master/hibernate-validator
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。