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 被注释的元素必须在合适的范围内

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

有些时候,在用户的应用中需要一些更复杂的 constraint。Bean Validation 提供扩展 constraint 的机制。可以通过两种方法去实现,一种是组合现有的 constraint 来生成一个更复杂的 constraint,另外一种是开发一个全新的 constraint。

创建一个包含验证逻辑的简单应用(基于 JSP)

在本文中,通过创建一个虚构的订单管理系统(基于 JSP 的 web 应用)来演示如何在 Java 开发过程中应用 Bean Validation。该简化的系统可以让用户创建和检索订单。

系统设计和运用的技术

图 1. 系统架构

图 1 是报表管理系统的结构图,是典型的 MVC(Model-View-Controller)应用。Controller 负责接收和处理请求,Servlet 扮演 Controller 的角色去处理请求、业务逻辑并转向合适的 JSP 页面。在 Servlet 中对数据进行验证。JSP 扮演 View 的角色以图型化界面的方式呈现 Model 中的数据方便用户交互。Model 就是此系统进行操作的数据模型,我们对这部分加以简化不对数据进行持久化。

数据模型

图 2. 数据模型

图 2 展示的是订单管理系统的数据模型。

声明了 contraint 的 JavaBean

清单 1. Order.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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 和 setter
 }

清单 2. Product.java
1
2
3
4
5
6
7
8
9
10
11
public class Product {
 // 必须非空
 @NotEmpty
 private String productName;
 // 必须在 8000 至 10000 的范围内
 // @Price 是一个定制化的 constraint
 @Price
 private float price;
 Getter 和 setter
 }

清单 3. OrderQuery.java
1
2
3
4
5
6
7
8
9
// 'to'所表示的日期必须在'from'所表示的日期之后
 // @QueryConstraint 是一个定制化的 constraint
 @QueryConstraint
 public class OrderQuery {
 private Date from;
 private Date to;
… omitted …
 Getter and setter
 }

定制化的 constraint

@Price是一个定制化的 constraint,由两个内置的 constraint 组合而成。

清单 4. @Price 的 annotation 部分
1
2
3
4
5
6
7
8
9
10
11
12
// @Max 和 @Min 都是内置的 constraint
@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.

清单 5. @Status 的 annotation 部分
1
2
3
4
5
6
7
8
9
@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 {};
}

清单 6. @Status 的 constraint validator 部分
1
2
3
4
5
6
7
8
9
10
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;
}
}

Bean Validation API 使用示例

创建订单

用户在创建一条订单记录时,需要填写以下信息:订单编号,客户,电子信箱,地址,状态,产品名称,产品价格

图 3. 创建订单

对这些信息的校验,使用 Bean Validation API

清单 7. 代码片段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
HttpSession session = req.getSession();
// 从 request 中获取输入信息
String orderId = (String) req.getParameter("orderId");
String customer = (String) req.getParameter("customer");
String email = (String) req.getParameter("email");
String address = (String) req.getParameter("address");
String status = (String) req.getParameter("status");
String productName = (String) req.getParameter("productName");
String productPrice = (String) req.getParameter("productPrice");
// 将 Bean 放入 session 中
Order order = new Order();
order.setOrderId(orderId);
order.setCustomer(customer);
order.setEmail(email);
order.setAddress(address);
order.setStatus(status);
order.setCreateDate(new Date());
Product product = new Product();
product.setName(productName);
if(productPrice != null && productPrice.length() > 0)
product.setPrice(Float.valueOf(productPrice));
order.setProduct(product);
session.setAttribute("order", order);
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Order>> violations = validator.validate(order);
if(violations.size() == 0) {
session.setAttribute("order", null);
session.setAttribute("errorMsg", null);
resp.sendRedirect("creatSuccessful.jsp");
} else {
StringBuffer buf = new StringBuffer();
ResourceBundle bundle = ResourceBundle.getBundle("messages");
for(ConstraintViolation<Order> violation: violations) {
buf.append("-" + bundle.getString(violation.getPropertyPath().toString()));
buf.append(violation.getMessage() + "<BR>\n");
}
session.setAttribute("errorMsg", buf.toString());
resp.sendRedirect("createOrder.jsp");
}
}

如果用户不填写任何信息提交订单,相应的错误信息将会显示在页面上

图 4. 验证后返回错误信息

其实在整个程序的任何地方都可以调用 JSR 303 API 去对数据进行校验,然后将校验后的结果返回。

转载于:https://www.cnblogs.com/zhengwuchao/p/8125360.html

关于Bean Validation相关推荐

  1. java validation_java bean validation 参数验证

    一.前言 在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节.比如参数不能为null,email那么必须符合email的格式,如果手动进行if判断或者写正则表达式判断无意开发效率太慢,在时间 ...

  2. JSR-303 Bean Validation 介绍及 Spring MVC 服务端验证最佳实践

    任何时候,当要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情. 应用程序必须通过某种手段来确保输入参数在上下文来说是正确的. 分层的应用在很多时候,同样的数据验证逻辑会出现在不同的层, ...

  3. JSR380(Bean Validation 2.0)

    1.新的变化 支持验证容器元素 集合类型的级联验证. 支持java.util.Optional 支持JavaFX的属性类型 支持自定义容器类型 支持新的日期/时间类型 新的内置约束:@Email, @ ...

  4. JSR349(Bean Validation 1.1)

    1.新增变化 1.1 依赖注入 Bean Validation使用组件MessageInterpolator, TraversableResolver, ParameterNameProvider, ...

  5. JSR303(Bean Validation 1.0)

    Bean Validation的1.0版本 1.约束定义 1.1 约束注解 Constraint 可用于字段.方法.属性.类型.注解类型,validatedBy返回的是ConstraintValida ...

  6. Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC

    http://sishuok.com/forum/blogPost/list/7798.html 在之前的<跟我学SpringMVC>中的<第七章 注解式控制器的数据验证.类型转换及 ...

  7. JSR 303 – Bean Validation 介绍及最佳实践

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

  8. JSR 303 - Bean Validation 介绍及最佳实践

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

  9. JSR303—Bean Validation验证

    JSR-303 Bean Validation 是 JAVA EE 6 中的一项子规范 官方参考实现是Hibernate Validator 此实现与 Hibernate ORM 没有任何关系 Bea ...

  10. Java数据校验(Bean Validation / JSR303)

    文档: http://beanvalidation.org/1.1/spec/ API : http://docs.jboss.org/hibernate/beanvalidation/spec/1. ...

最新文章

  1. 陌陌财报双双超预期,什么才是它的基本盘?
  2. 基于 Quartz 开发企业级任务调度应用
  3. Windows 下开发PHP扩展资源
  4. 清华“最强本科生”揭晓!网友:我大概是来凑数的……
  5. spring boot html乱码,Spring-boot 字符集设置 解决乱码方案
  6. Mac下配置Android环境
  7. 书籍-Druid实时大数据分析原理与实践
  8. WinRAR各版本许可注册码
  9. 最新emoji表情代码大全_7张最新有创意好看的早安问候动画表情图片 暖心的早上好问候祝福动态图片表情大全...
  10. win10中修改mac地址
  11. webrtc音频QOS方法四(音频接收端NACK流程实现)
  12. android图片自动翻转,android图片翻转镜像
  13. session跨域共享
  14. matlab模拟退火算法工具箱下载,Matlab的模拟退火算法工具箱
  15. 支付宝支付 62009
  16. SysinternalsSuite
  17. 【java感悟】接口,抽象类的关系
  18. hdlc协议解码的四种方法
  19. 7-1 用格里高利公式求给定精度的PI值 (15分)
  20. Properties 文件中字符串加了引号

热门文章

  1. 【渝粤题库】陕西师范大学180213《消费经济学》作业 (高起本)
  2. 【渝粤教育】广东开放大学 建筑专业 形成性考核 (57)
  3. 学习C/C++的经验谈
  4. [洛谷P4052][JSOI2007]文本生成器
  5. [.NET领域驱动设计实战系列]专题十:DDD扩展内容:全面剖析CQRS模式实现
  6. 用Appscan 作代理,录制APP页面的限制条件
  7. Directx教程(28) 简单的光照模型(7)
  8. [dotnet]以最小的成本,落地微服务特色的DevOps管道,持续集成/部署到kubernetes。...
  9. 必看谈谈数据库的锁机制!!
  10. 伪装Apache版本防止入侵Web服务器