使用validator框架来validate bean

简介:

 在数据传递,尤其当你准备好发送一个请求到其他系统前,对于bean的取值做必要的校验是十分重要的。

对于一些简单的字段,JSR已经提供了一些annotation比如@NotNull , @NotEmpty来完成,我们这里主要来讨论比较复杂的校验:

 

需求

假设我们在数据模型AppInfo中有一个字段叫Tenant,这个tenant是个字符串类型,并且它的取值只可能是{"US","Brazil","ASDA","Canada","Multi-tenant"} ,那么我们如何校验这个数据模型呢?

 

解决方法

很简单,首先我们自定义一个Validator类来封装校验逻辑,它要求我们实现isValid()方法:

/**  * Validator class definition to validate the tenant field of AppService  * datamodel  *   * @author cwang58  * @created date: Jan 28, 2013  */ public class TenantValidator implements ConstraintValidator<Tenant, String> {      private final String[] ALL_TENANT_TYPE = { "US", "Brazil", "ASDA",             "Canada", "Multi-tenant" };      @Override     public void initialize(Tenant tenant) {      }      /**      * validation logic to identifiy whether the field which annotatied by @Tenant is valid or invalid      */     @Override     public boolean isValid(String value, ConstraintValidatorContext context) {         if (Arrays.asList(ALL_TENANT_TYPE).contains(value)) {             return true;         }         return false;     }  }

 

其次,我们定义一个注解接口 @Tenant,并且让这个注解接口使用我们刚才定义的Validator类作为其校验类,我们这类是可以标注在字段或者方法上的。

/**  * Annotation of Tenant to validate the "tenant" field of AppInfo  *@author cwang58  *@created date: Jan 28, 2013  */   @Constraint(validatedBy = {TenantValidator.class})  @Documented  @Target( { ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD })  @Retention(RetentionPolicy.RUNTIME)  public @interface Tenant {  String message() default " only support tenant type of ['US','Brazil','ASDA',Canada','Multi-tenant']";  Class<?>[] groups() default {};  Class<? extends Payload>[] payload() default {};  }

 

现在我们在目标数据模型中相应的字段上使用我们开发的标注就可以了,见27-28行:

 

/**  * this is the data model for appinfo  *@author cwang58  *@created date: Jan 24, 2013  */   public class AppInfo implements Serializable {          /**      *       */     private static final long serialVersionUID = 3L;          @NotNull     private String groupId;          @NotNull     private String artifactId;          @NotNull     private String versionNo;          @NotNull     private boolean isPCIApplication;          @Tenant     private String tenant;          @NotEmpty     private String ri;  ...

 

现在我们来编写校验方法,我们在业务方法createAppInfo()中加入以下代码,这样在创建数据模型时会完成我们的校验逻辑:

/**      * build the AppInfo object based on the appInfoJsonString      */     public AppInfo createAppInfo(String appInfoJSONString) {          if ((appInfoJSONString == null) || ("".equals(appInfoJSONString)))             return null;          JSONObject appInfoJSON;         try {             appInfoJSON = new JSONObject(appInfoJSONString);              String groupId = appInfoJSON.getString("groupId");             String artifactId = appInfoJSON.getString("artifactId");             String versionNo = appInfoJSON.getString("versionNo");             boolean isPCIApplication = Boolean.parseBoolean(appInfoJSON                     .getString("isPCIApplication"));             String tenant = appInfoJSON.getString("tenant");             String ri = appInfoJSON.getString("ri");             String appRunningEnv = appInfoJSON.getString("appRunningEnv");             //Date goLiveDate = new Date(appInfoJSON.getLong("goliveDate"));             String goLiveDate = appInfoJSON.getString("goliveDate");                        // Parse docInfos             JSONArray docInfos = appInfoJSON.getJSONArray("docInfos");             List<DocInfo> docInfoList = new ArrayList<DocInfo>();             for (int i = 0; i < docInfos.length(); i++) {                 JSONObject docInfoJSON = docInfos.getJSONObject(i);                 String bookTitle = docInfoJSON.getString("title");                 String bookUrl = docInfoJSON.getString("url");                 docInfoList.add(new DocInfo(bookTitle, bookUrl));             }             AppInfo appInfo = new AppInfo(groupId, artifactId, versionNo,                     isPCIApplication, tenant, ri, appRunningEnv, goLiveDate,                     docInfoList);             ValidatorFactory factory = Validation.buildDefaultValidatorFactory();               Validator validator = factory.getValidator();               //begin validate              Set<ConstraintViolation<AppInfo>> violations = validator.validate(appInfo);               if(violations.size() == 0) {                   return appInfo;              } else {                   StringBuilder volidationFailureSB = new StringBuilder() ;                  for(ConstraintViolation<AppInfo> violation: violations) {                   volidationFailureSB.append("-" + violation.getPropertyPath().toString());                   volidationFailureSB.append(violation.getMessage() +"\n");                   }                   logger.error("validation failure as follows:");                  logger.error(volidationFailureSB.toString());                  return null;              }  ...

从38行开始就会让校验框架来进行校验,我们首先获得ValidatorFactory,然后获得Validator对象(这是jsr的validator),然后从第41行开始校验,并且把校验的违背结果放入violations集合对象中,如果集合对象size()为0 ,那么就说明数据模型没有违背的地方,所以正常创建数据模型,否则,从46行开始,我们把所有违背的地方全部罗列出来,并且写入日志。

 

实验:

如果用户在前端对于tenant字段传递的不是我们所要的合法tenant值,比如"tenant1":


 

 

最终,日志就可以看出,吧这行非法内容检查了出来:


[Server Log]  validation failure as follows:  -tenant only support tenant type of ['US','Brazil','ASDA',Canada','Multi-tenant']




本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1138795,如需转载请自行联系原作者

目录
相关文章
|
Java 数据库连接 API
【hibernate validator】(二)声明和验证Bean约束(下)
【hibernate validator】(二)声明和验证Bean约束(下)
|
Java 数据库连接 容器
【hibernate validator】(二)声明和验证Bean约束(上)
【hibernate validator】(二)声明和验证Bean约束
|
Java 数据库连接 mybatis
【Spring常见错误】No qualifying bean of type
📋📋 精彩摘要:MyBatis 核心配置文件(xxxConfig.xml),该文件配置了MyBatis的一些全局信息,,包含数据库连接信息和MyBatis运行时所需的各种特性,以及设置和响应MyBatis行为的一些属性。本文将深入浅出的介绍MyBatis核心配置文件中常用的标签配置。
5140 0
|
5月前
|
XML 前端开发 Java
SpringBoot参数校验@Validated、@Valid(javax.validation)详解
SpringBoot参数校验@Validated、@Valid(javax.validation)
596 4
|
11月前
|
Java 数据库连接
hibernate-validator校验对象属性为List
hibernate-validator校验对象属性为List
186 1
|
前端开发 Java 数据库连接
Hibernate Validator -- 伟大的校验器
validator Engine 是支持Javax.validator 的接口的实现, 并且可以通过一些简单的标注的形式(annotation形式)实现一个校验的形式, 它其实也是一个约定大于执行的过程
155 0
|
Java Spring
Spring data Jpa 提供的validator验证
Spring data Jpa 提供的validator验证
122 0
Spring data Jpa 提供的validator验证
|
Java 数据库连接
SpringBoot 2.0参数校验Hibernate Validator
SpringBoot 2.0参数校验Hibernate Validator
SpringBoot 2.0参数校验Hibernate Validator
Springboot使用hibernate-validator实现参数校验
Springboot使用hibernate-validator实现参数校验
260 0
Springboot使用hibernate-validator实现参数校验
|
JSON 前端开发 Java
Validated、Valid 、Validator,他们的区别你知道几个
Validated、Valid 、Validator,他们的区别你知道几个
611 0
Validated、Valid 、Validator,他们的区别你知道几个