前言
实际开发过程中,免不了参数校验,而每个接口中都写一大段基本类似的参数校验代码,代码冗余不说,如果某个对象的某个属性的判断条件有变化,还需要修改每个接口的判断条件,降低了代码可读性和可维护性,所以引入validation注解来简化接口中的参数判断的代码
一、引入Maven依赖
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
二、新建用于分组校验的接口(如果需要分组校验)
package com.web.demo.entity.validate;
/**
* 分组校验接口
* 实现效果为:
* validation注解的groups传入ValidateGroup时,表示添加、更新都不允许为空
* validation注解的groups传入Create时,表示添加时不允许为空
* validation注解的groups传入Update时,表示修改时不允许为空(比如Id字段)
*
* @author zhangYiCong
* @date 2021-07-13 15:56:40
*/
public interface ValidateGroup {
/**
* 分组校验,用于标记新建时字段校验
*/
interface Create extends ValidateGroup {
}
/**
* 分组校验,用于标记更新时字段校验
*/
interface Update extends ValidateGroup {
}
}
三、标题在实体类上加入相应注解
package com.web.demo.entity;
import com.web.demo.entity.validate.ValidateGroup;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 学生类,用来实现crud
*
* @author zhangYiCong
* @date 2021-07-12 16:16:52
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Student implements Serializable {
private static final long serialVersionUID = 8719825047423144651L;
//更新时不允许为空
@NotEmpty(message = "id不能为空", groups = ValidateGroup.Update.class)
private String id;
//添加、更新时都不允许为空
@NotEmpty(message = "name不能为空", groups = ValidateGroup.class)
private String name;
private int age;
//添加时不允许为空
@NotNull(message = "gender不能为空", groups = ValidateGroup.Create.class)
private Boolean gender;
private String phoneNum;
}
四、新建参数校验工具类
package com.web.demo.util;
import com.web.demo.entity.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Set;
/**
* 参数校验器
*
* @author zhangYiCong
* @date 2021-07-13 15:31:16
*/
public class ValidateUtil {
private final static Logger LOGGER = LoggerFactory.getLogger(ValidateUtil.class);
private static ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
/**
* 传入对象,校验被validation注解标注的参数
*
* @param request 需要校验的类
* @param groups 分组校验
* @param <T>
* @return Response 自定义统一返回值
*/
public static <T> Response validateResult(T request, Class<?>... groups) {
Response response = new Response();
if (request == null) {
response.fill("10001", "缺少参数, 或参数有误");
return response;
}
//获取校验器
Validator validator = factory.getValidator();
//校验传入的对象被validation注解标注的参数
Set<ConstraintViolation<T>> constraintViolations = validator.validate(request, groups);
StringBuilder stringBuilder = new StringBuilder();
//遍历违反约束的对象,拼接错误原因
for (ConstraintViolation<T> constraintViolation : constraintViolations) {
stringBuilder.append(constraintViolation.getMessage()).append(",");
}
//封装返回结果
if (!CollectionUtils.isEmpty(constraintViolations)) {
String errorMsg = String.format("缺少参数, 或参数有误:[%s]", stringBuilder.toString());
LOGGER.warn(errorMsg);
response.fill("10001", errorMsg);
return response;
}
return response;
}
}
五、测试
测试代码如下:
public static void main(String[] args) {
Student student = new Student();
Response response = ValidateUtil.validateResult(student, ValidateGroup.class);
System.out.println(JSON.toJSONString(response));
System.out.println("--------- 添加、更新时参数校验 -----------");
Student student2 = new Student();
Response response2 = ValidateUtil.validateResult(student2, ValidateGroup.Update.class);
System.out.println(JSON.toJSONString(response2));
System.out.println("--------- 更新时参数校验 -----------");
Student student3 = new Student();
Response response3 = ValidateUtil.validateResult(student3, ValidateGroup.Create.class);
System.out.println(JSON.toJSONString(response3));
System.out.println("--------- 添加时参数校验 -----------\n\n");
Student student4 = Student.builder()
.name("Tom")
.gender(true)
.build();
Response response4= ValidateUtil.validateResult(student4, ValidateGroup.Create.class);
System.out.println(JSON.toJSONString(response4));
System.out.println("--------- 添加时参数校验 -----------");
Student student5 = Student.builder()
.id("1")
.name("Tom")
.build();
Response response5= ValidateUtil.validateResult(student5, ValidateGroup.Update.class);
System.out.println(JSON.toJSONString(response5));
System.out.println("--------- 修改时参数校验 -----------");
Student student6 = Student.builder()
.name("Tom")
.build();
Response response6= ValidateUtil.validateResult(student6, ValidateGroup.class);
System.out.println(JSON.toJSONString(response6));
System.out.println("--------- 添加、修改时参数校验 -----------");
}
测试结果如下:
2021-07-13 16:21:45.401 [main] WARN com.web.demo.util.ValidateUtil[validateResult:58] -缺少参数, 或参数有误:[name不能为空,]
{"code":"10001","message":"缺少参数, 或参数有误:[name不能为空,]","success":false}
--------- 添加、更新时参数校验 -----------
2021-07-13 16:21:45.519 [main] WARN com.web.demo.util.ValidateUtil[validateResult:58] -缺少参数, 或参数有误:[id不能为空,name不能为空,]
{"code":"10001","message":"缺少参数, 或参数有误:[id不能为空,name不能为空,]","success":false}
--------- 更新时参数校验 -----------
2021-07-13 16:21:45.520 [main] WARN com.web.demo.util.ValidateUtil[validateResult:58] -缺少参数, 或参数有误:[gender不能为空,name不能为空,]
{"code":"10001","message":"缺少参数, 或参数有误:[gender不能为空,name不能为空,]","success":false}
--------- 添加时参数校验 -----------
{"code":"0","message":"success","success":true}
--------- 添加时参数校验 -----------
{"code":"0","message":"success","success":true}
--------- 修改时参数校验 -----------
{"code":"0","message":"success","success":true}
--------- 添加、修改时参数校验 -----------