Java参数校验工具validation实践
介绍
在项目开发当中,数据校验是你必须要考虑和面对的事情,为此要写上一大串的代码进行校验,这样就会导致代码冗余和一些管理的问题。
例如下面的代码:
public void push(List<Long> userList, String url, String content) {
Preconditions.checkArgument(CollectionUtils.isNotEmpty(userList), "用户列表不能为空");
Preconditions.checkArgument(StringUtils.isNotEmpty(url), "推送url不能为空");
Preconditions.checkArgument(StringUtils.isNotEmpty(content), "推送内容不能为空");
}
validation可以做以下事情
- validation可以抛出统一的参数校验异常,方便定位问题
- 编程简单,只需要注解就能搞定,不需要编写大量的代码
validation提供以下注解:

使用
添加JAR包依赖
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<!-- hibernate validator-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.0.Final</version>
</dependency>
一、简单的参数校验
public class UserBean {
@Range(min = 20, max = 50, message = "age应该在[20,50]之间")
private Integer age;
@NotNull(message = "name不能为空")
private String name;
@Length(max = 100, message = "address不能超过100")
private String address;
@Email(message = "email格式不对")
private String email;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
创建对象验证器
/**
* 对象验证器
*
* Created by Albert on 18/1/25.
*/
public class BeanValidator { /**
* 验证某个bean的参数
*
* @param object 被校验的参数
* @throws ValidationException 如果参数校验不成功则抛出此异常
*/
public static <T> void validate(T object) {
//获得验证器
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
//执行验证
Set<ConstraintViolation<T>> constraintViolations = validator.validate(object);
//如果有验证信息,则取出来包装成异常返回
if (CollectionUtils.isEmpty(constraintViolations)) {
return;
}
throw new ValidationException(convertErrorMsg(constraintViolations));
} /**
* 转换异常信息
* @param set
* @param <T>
* @return
*/
private static <T> String convertErrorMsg(Set<ConstraintViolation<T>> set) {
Map<String, StringBuilder> errorMap = new HashMap<>();
String property;
for (ConstraintViolation<T> cv : set) {
//这里循环获取错误信息,可以自定义格式
property = cv.getPropertyPath().toString();
if (errorMap.get(property) != null) {
errorMap.get(property).append("," + cv.getMessage());
} else {
StringBuilder sb = new StringBuilder();
sb.append(cv.getMessage());
errorMap.put(property, sb);
}
}
return errorMap.toString();
}
}
编写测试类
public class ValidatorTest {
public static void main(String[] args) {
UserBean userBean = new UserBean();
userBean.setAge(12);
userBean.setName("张三");
userBean.setAddress("124444444112");
userBean.setEmail("123");
BeanValidator.validate(userBean);
}
}
运行结果

二、自定义验证器
定义注解,message、groups和payload三个属性是必须定义的。
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ZipCodeValidator.class)
public @interface ZipCode {
String message() default "";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
定义验证类
public class ZipCodeValidator implements ConstraintValidator<ZipCode, String> {
private String zipCodeReg = "[1-9]d{5}(?!d)";//表示邮编的正则表达式
private Pattern zipCodePattern = Pattern.compile(zipCodeReg);
@Override
public void initialize(ZipCode zipCode) {
}
@Override
public boolean isValid(String val, ConstraintValidatorContext constraintValidatorContext) {
if(val == null) {
return true;
}
return zipCodePattern.matcher(val).matches();
}
}
UserBean 加入以下代码
@ZipCode(message = "邮编格式错误")
private String zipCode; public String getZipCode() {
return zipCode;
} public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
编写测试类
public class ValidatorTest {
public static void main(String[] args) {
UserBean userBean = new UserBean();
userBean.setAge(12);
userBean.setName("张三");
userBean.setAddress("124444444112");
userBean.setEmail("123");
userBean.setZipCode("000111");
BeanValidator.validate(userBean);
}
}
运行结果

结语
本文只列举了部分常用的校验方法,还有更多的使用方式,就不在这里一一列举了。
Java参数校验工具validation实践的更多相关文章
- Java Bean Validation(参数校验) 最佳实践
转载来自:http://www.cnblogs.com 参数校验是我们程序开发中必不可少的过程.用户在前端页面上填写表单时,前端js程序会校验参数的合法性,当数据到了后端,为了防止恶意操作,保持程序的 ...
- Java web服务端参数校验Javax.validation (springboot)
一.基本使用 Javax.validation是spring集成自带的一个参数校验接口.可通过添加注解来设置校验条件. 下面以springboot项目为例进行说明.创建web项目后,不需要再添加其他的 ...
- Java参数验证Bean Validation 框架
1.为什么要做参数校验? 参数校验和业务逻辑代码分离,参数校验代码复用,统一参数校验方式.校验不太通过时统一异常描述. 2.bean validation规范 JSR303 规范(Bean Valid ...
- Java数据校验(Bean Validation / JSR303)
文档: http://beanvalidation.org/1.1/spec/ API : http://docs.jboss.org/hibernate/beanvalidation/spec/1. ...
- 前端参数统一校验工具类ValidParamUtils
1,前端参数不可信,对于后端开发人员来说应该是一条铁律,所以对于前端参数的校验,必不可少,而统一的前端参数校验工具,对我们进行参数校验起到事半功倍的效果 2,统一参数校验工具ValidParamUti ...
- 【spring】-- jsr303参数校验器
一.为什么要进行参数校验? 当我们在服务端控制器接受前台数据时,肯定首先要对数据进行参数验证,判断参数是否为空?是否为电话号码?是否为邮箱格式?等等. 这里有个问题要注意: 前端代码一般上会对这些数据 ...
- Spring Validation最佳实践及其实现原理,参数校验没那么简单!
之前也写过一篇关于Spring Validation使用的文章,不过自我感觉还是浮于表面,本次打算彻底搞懂Spring Validation.本文会详细介绍Spring Validation各种场景下 ...
- javax.validation参数校验
在实体字段加注解: /** * 机构名称 */ @ApiParam(name = "orgName", value = "机构名称") @Size(max = ...
- 利用 Bean Validation 来简化接口请求参数校验
团队新来了个校招实习生静静,相互交流后发现竟然是我母校同实验室的小学妹,小学妹很热情地认下了我这个失散多年的大湿哥,后来... 小学妹:大湿哥,咱们项目里的 Controller 怎么都看不到参数校验 ...
随机推荐
- 关于idea中,web项目启动tomcat,访问资源报错404
背景: web项目启动tomcat,访问相应的资源,报错404,前提资源路径是没错的. 原因: 1.确定是不是web项目 不是的话: 配置web-inf的路径和webroot(web根目录)的路径 2 ...
- Nginx:413 Request Entity Too Large 的解决方法
报错信息413 Request Entity Too Large 解决方法: (20M大小,自己调节,根据文件大小.)修改 php 的配置文件 /etc/php5/fpm/php.ini upload ...
- python下pip使用bug汇总
PS:以下操作全部基于win10 64位操作系统 pip安装任何包都出现问题: Cannot unpack file /tmp/pip-KzJgHD-unpack/simple 报错: Cannot ...
- Redis的持久化和主从复制机制
Redis持久化 Redis 提供了多种不同级别的持久化方式: RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot) AOF 持久化记录服务器执行 ...
- [190308]Ubuntu 安装完之后,安装的软件小记
install software vim sudo apt-get install -y vim Typora command copy from Typora website # or run: # ...
- windows2012 日志查看过程
Windows2012界面修改好造成有些人不知道在哪里查找windows 日志 我这边截图描述一下 1. 2.输入 命令 eventvwr.msc 3.弹出 windows 事件查看器 4.若需要 ...
- 从服务器上下载下来的代码,部署到本地时,Url自动带www前缀
fix步骤: 1.网站根目录下,找到.htacess文件,有记事本打开 2.定位到 RewriteCond %{HTTP_HOST} . RewriteCond %{HTTP_HOST} !^www\ ...
- leetcood学习笔记-2-两数相加
题目描述: 方法一: # Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.va ...
- Redis 常用的数据结构
String 字符串 set get 使用场景: 可以用来作为缓存使用(缓存更新策略和缓存雪崩如何处理) List lpop rpop lpush rpush 使用场景: set 无序集合 使用场景: ...
- expect离线安装
expect5.45.4.tar.gz和tcl8.4.11-src.tar.gz压缩包请前往以下链接下载: https://download.csdn.net/download/gangzi221/1 ...