内容
- Bean Validation(JSR-303):介绍 Java Bean 验证、核心 API、实现框架 Hibernate Validator
- Apache commons-validator :介绍最传统 Apache 通用验证器框架,如:长度、邮件等方式
- Spring Validator:介绍 Spring 内置验证器 API、以及自定义实现
Bean Validation 1.1 JSR-303
Maven依赖
1 | <dependency> |
命名规则(Since Spring Boot 1.4):Spring Boot大多数情况采用
starter
(启动器,包含一些自动装配的Spring组建),官方的命名规则:spring-boot-starter-{name}
。非官方采用{name}-spring-boot-starter
代码示例
1 | import javax.validation.constraints.Max; |
1 | import com.bai.springbootvalidation.domain.User; |
请求时,当id>10000或name为null时,会报错。
- 优点
- 节省代码。
- 其它方式
- API方式
Assert.hasText(user.getName(),"名称不能为空");
- 不能为空,必须有文字
- 返回500
- JVM断言
assert user.getId() <= 10000;
- 返回400
- 缺点
- 耦合了业务逻辑,虽然可以通过
HandlerInterceptor
或Filter
做拦截,但是也是非常不优雅的。 - 还可以通过AOP方式,也可以提升代码的可读性。
- 以上方式都不是统一的标准
- 耦合了业务逻辑,虽然可以通过
- API方式
自定义Bean Validation
通过员工的卡号来校验,需要通过工号的前缀和后缀来判断。前缀必须以2BAI-
开头。后缀必须以数字
结尾。需要通过Bean Validation校验。
实现步骤
- 复制成熟 Bean Validation Annotation的模式
1 | (FIELD) |
- 参考和理解@Constraint
- 实现ConstraintValidator 接口
- 将实现ConstraintValidator 接口 定义到@Constraint#validatedBy
- 给@ValidCardNumber 添加 message 参数
补充内容
org.springframework.util.StringUtils.delimitedListToStringArray
来分割字符串取代Split
- 该方法使用了正则表达式
- 其次是空指针NPE保护不够
- 如果在依赖中没有
StringUtils.delimitedListToStringArray
,可以使用JDK
里的StringTokenizer
(不足:类似于枚举Enumeration
)或org.apache.commons.lang3.StringUtils
- 采用三方类库时,尽量用一套类库,不要A库用一点,B库用一点。
Q&A
Q:JSON校验如何办?
A:尝试变成 Bean 的方式。
Q:实际中很多参数都要校验,这样写会增加很多类
A:确实会增加部分工作量,大多数场景,不需要自定义,除非很特殊情况。Bean Validation 的主要缺点,单元测试不方便。需要拿到Annotation,然后构造参数去测试。
Q:如果前端固定表单的话,这种校验方式很好。但是灵活性不够,如果表单是动态的话,如何校验呢?
A:表单字段与 Form 对象绑定即可,再走 Bean Validation 逻辑。
1 | <form action="" method="POST" command="form"> |
也可以通过责任链模式(Pipeline),一个接一个验证:
field 1-> field 2 -> field 3 -> compute -> result
Q:如何自定义,返回格式?如何最佳实现?
A:可以通过REST来实现,比如 XML 或者 JSON 的格式(视图)。