JSR-303 是 JAVA EE 6 中的一项子规范,叫做 Bean Validation,官方参考实现是Hibernate Validator。此实现与 Hibernate ORM 没有任何关系。JSR 303 用于对 Java Bean 中的字段的值进行验证。Spring MVC 3.x 之中也大力支持 JSR-303,可以在控制器中对表单提交的数据方便地验证
JSR 303 内置的约束规则 :
验证适用字段 | 注解说明 | 属性说明 | |
@AssertTrue/@AssertFalse | boolean | 验证值是否为 true / false | |
@DecimalMax/@DecimalMin | BigDecimal,BigInteger,String,byte,short,int,long | 验证值是否小于或者等于指定的小数值,要注意小数存在精度问题 | 公共 |
@Digits | BigDecimal,BigInteger,String,byte,short,int,long | 验证值的数字构成是否合法 |
integer : 指定整数部分的数字的位数
fraction : 指定小数部分的数字的位数
|
@Future/@Past | Date,Calendar | 验证值是否在当前时间之后/之前 | 公共 |
@Max/@Min
@DecimalMax/@DecimalMin
| BigDecimal,BigInteger,String,byte,short,int,long | 验证值是否小于或者等于指定的整数值,不建议使用在int类型上 | 公共 |
@NotNull/@Null | 引用数据类型 | 验证值是否为非空/空,无法查检长度为0的字符串 | 公共 |
@NotEmpty | string,collection,map,array | 检查约束元素是否为NULL或者是EMPTY | |
@NotBlank | 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格 | ||
@Pattern | String | 验证值是否配备正则表达式 |
regexp : 正则表达式
flags : 指定 Pattern.Flag 的数组,表示正则表达式的相关选项
|
@Size/@Range | String,Collection,Map,数组 | 验证值是否满足长度要求 |
max : 指定最大长度
min : 指定最小长度
|
@Length | String | 检查字符串是否在指定范围内 | |
@Valid | 引用类型 | 验证值是否需要递归验证 | 无 |
@CreditCardNumber | 信用卡验证 | ||
验证是否是邮件地址,如果为null,不进行验证,算通过验证 |
所有标记都有 message 代表错误提示信息
环境配置 : 需要以下两个校验包
validation-api.jar : JDK的接口
hibernate-validator.jar : 是对上述接口的实现
public class
ValidateTest {
@NotNull(message =
"必须不为 null")
@Size(min =
5, max =
10, message =
"最大是 10,最小是 5,null元素被认定为有效")
public
List<String>
orders;
@Length(min =
5, max =
10, message =
"检查字符串是否在 5 至 10之间,包括 5 和 10")
public
String
orderId;
@Null(message =
"必须为 null")
public
String
nullData;
@NotBlank(message =
"@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格")
public
String
name;
@NotEmpty(message =
"@NotEmpty 检查约束元素是否为NULL或者是EMPTY")
public
String
describ;
@AssertTrue(message =
"@AssertTrue 验证 Boolean 对象是否为 true")
public boolean
isEnable;
@AssertFalse(message =
"@AssertFalse 验证 Boolean 对象是否为 false")
public boolean
isNotEnable;
@Max(value =
10, message =
"len 不超过10")
@Min(value =
5, message =
"len 不低于5")
public
Number
len;
@NotNull(message =
"adultTaxType不能为空")
@Min(value =
0, message =
"adultTaxType 的最小值为0")
@Max(value =
1, message =
"adultTaxType 的最大值为1")
public
Integer
adultTaxType;
/** 订单取消原因 */
@NotNull(message =
"reason信息不可以为空")
@Pattern(regexp =
"[1-7]{1}", message =
"reason的类型值为1-7中的一个类型")
public
String
reason;
@DecimalMax(value =
"100", message =
"年龄不能超过100岁")
@DecimalMin(value =
"1", message =
"年龄不能低于1岁")
public int
age;
@Digits(integer =
4, fraction =
4, message =
"整数部分最大4位,小数部分最大4位")
public
String
ratio;
@Range(min =
5, max =
10, message =
"限制长度在 5~10 之间")
public
String
song;
@CreditCardNumber(message =
"信用卡验证")
public
String
creditCardNumber;
@Email(message =
"验证是否是邮件地址,如果为null,不进行验证,算通过验证")
public
String
email;
@URL
public
String
url;
/**
* 验证注解的完整方法
*/
public void
validateParams() {
// 调用JSR303验证工具,校验参数
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<ValidateTest>> violations = validator.validate(this);
Iterator<ConstraintViolation<ValidateTest>> iter = violations.iterator();
if
(iter.hasNext()) {
String errMessage = iter.next().getMessage();
throw new
ValidationException(errMessage);
}
}
public static void
main(String[] args) {
ValidateTest validateTestClass =
new
ValidateTest();
validateTestClass.orders
=
new ArrayList<>(4);
validateTestClass.validateParams();
// 调用验证的方法
}
}
使用 Spring MVC 和 JSR-303 的标注做表单提交的服务器端验证时,需校验的表单命令对象和其绑定结果对象或错误对象时成对出现的,它们之间不允许声明其他的入参
@Valid 标注的 Command 对象和 BindingResult 参数一定要紧挨着,要不然数据绑定错误直接抛异常,不会封装成一个 BindingResult 对象
Errors 接口提供了获取错误信息的方法,如 getErrorCount() 或 getFieldErrors(String field) BindingResult 扩展了 Errors 接口
@RequestMapping("/testJSR303")
public
String testJSR303(@Valid
User user5, Errors errors) {
System.out.println(errors.getErrorCount());
// getErrorCount() : 打印错误消息的数量
// 遍历错误消息
if
(errors.getErrorCount() >
0) {
List<FieldError> fieldErrors = errors.getFieldErrors();
// getFieldErrors() : 获取所有错误 Field
for
(FieldError error : fieldErrors) {
System.out.println(error.getDefaultMessage());
}
}
return
"success";
}
在 SpringMVC 中通过 @Valid 将会验证入参
在 Dubbo 中添加 validation="true" 属性
在服务端 :
<dubbo:service
interface="com.alibaba.dubbo.examples.validation.api.ValidationService"
ref="validationService"
validation="true"/>
在消费端 :
<dubbo:reference
id="validationService"
interface="com.alibaba.dubbo.examples.validation.api.ValidationService"
validation="true"/>