JSR 303 Bean Validation

JSR 303 Bean Validation

JSR 303 – Bean Validation 规范

简介

在任何时候,当你要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情。
应用程序必须通过某种手段来确保输入进来的数据从语义上来讲是正确的。
在通常的情况下,应用程序是分层的,不同的层由不同的开发人员来完成。
很多时候同样的数据验证逻辑会出现在不同的层,这样就会导致代码冗余和一些管理的问题,比如说语义的一致性等。
为了避免这样的情况发生,最好是将验证逻辑与相应的域模型进行绑定。

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

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)被注释的元素必须符合指定的正则表达式

一个 constraint 通常由 annotation 和相应的 constraint validator 组成,它们是一对多的关系。
也就是说可以有多个 constraint validator 对应一个 annotation。
在运行时,Bean Validation 框架本身会根据被注释元素的类型来选择合适的 constraint validator 对数据进行验证。

Hibernate Validator 附加的 constraint

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

定制化的 constraint

DEMO
@Getter@Setter
public class Order { 
    // 必须不为 null, 大小是 10 
    @NotNull 
    @Size(min = 10, max = 10) 
    private String orderId; 
    // 必须不为空
    @NotEmpty 
    private String customer; 
    // 必须是一个电子信箱地址
    @Email 
    private String email; 
    // 必须不为空
    @NotEmpty 
    private String address; 
    // 必须不为 null, 必须是下面四个字符串'created', 'paid', 'shipped', 'closed'其中之一
    // @Status 是一个定制化的 contraint 
    @NotNull 
    @Status 
    private String status; 
    // 必须不为 null 
    @NotNull 
    private Date createDate; 
    // 嵌套验证
    @Valid 
    private Product product; 
 }
@Getter@Settter
public class Product { 
    // 必须非空
    @NotEmpty 
    private String productName; 
    // 必须在 8000 至 10000 的范围内
    // @Price 是一个定制化的 constraint 
    @Price 
    private float price;
}

@Price 的实现

@Max(10000) 
@Min(8000) 
@Constraint(validatedBy = {}) 
@Documented 
@Target( { ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD }) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface Price { 
    String message() default "错误的价格"; 
    Class<?>[] groups() default {}; 
    Class<? extends Payload>[] payload() default {}; 
}

@Status 的实现

@Constraint(validatedBy = {StatusValidator.class}) 
@Documented 
@Target( { ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD }) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface Status { 
    String message() default "不正确的状态 , 应该是 'created', 'paid', shipped', closed'其中之一"; 
    Class<?>[] groups() default {}; 
    Class<? extends Payload>[] payload() default {}; 
}


public class StatusValidator implements ConstraintValidator<Status, String>{ 
    private final String[] ALL_STATUS = {"created", "paid", "shipped", "closed"}; 
    public void initialize(Status status) { 
    }

    public boolean isValid(String value, ConstraintValidatorContext context) { 
    if(Arrays.asList(ALL_STATUS).contains(value)) 
        return true; 
        return false; 
    }
}

校验

ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 
Validator validator = factory.getValidator(); 
Set<ConstraintViolation<Order>> violations = validator.validate(order); 

// violations 中包含错误信息, 否则 size = 0

END

JSR 303 的发布使得在数据自动绑定和验证变得简单,使开发人员在定义数据模型时不必考虑实现框架的限制。
当然 Bean Validation 还只是提供了一些最基本的 constraint,在实际的开发过程中,用户可以根据自己的需要组合或开发出更加复杂的 constraint

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值