天天看点

使用validation注解实现参数校验

前言

实际开发过程中,免不了参数校验,而每个接口中都写一大段基本类似的参数校验代码,代码冗余不说,如果某个对象的某个属性的判断条件有变化,还需要修改每个接口的判断条件,降低了代码可读性和可维护性,所以引入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}
--------- 添加、修改时参数校验 -----------