JavaBean参数校验

一、 JSR303,Hibernate Validator 等校验工具的使用,以及自定义校验注解的使用

1.1  JSR303校验标准

JSR303是一套JavaBean参数校验的标准,它定义了很多常用的校验注解,我们可以直接将这些注解加在我们JavaBean的属性上面,就可以在需要校验的时候进行校验了。注解如下:

1.2 Hibernate validator扩展

Hibernate validator 在JSR303的基础上对校验注解进行了扩展,扩展注解如下:

Spring validtor 同样扩展了jsr303,并实现了方法参数和返回值的校验

Spring 提供了MethodValidationPostProcessor类,用于对方法的校验

1.3  @NotEmpty,@NotNull和@NotBlank的区别


1.3.1  @NotEmpty :不能为null,且Size>0

1.3.2  @NotNull:不能为null,但可以为empty,没有Size的约束

1.3.3  @NotBlank:只用于String,不能为null且trim()之后size>0

二、基础校验类型

2.1    在pom.xml中添加如下依赖

<!--jsr 303-->
        <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>

2.2  校验工具类

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.groups.Default;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * javabeanValidator
 */
public class ValidatorUtils {


    private static Validator validator = Validation.buildDefaultValidatorFactory()
            .getValidator();


    public static <T> Map<String, String> validate(T obj) {
        Map<String, StringBuilder> errorMap = new HashMap<>();
        Set<ConstraintViolation<T>> set = validator.validate(obj, Default.class);
        if (set != null && set.size() > 0) {
            String property = null;
            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.entrySet().stream().collect(Collectors.toMap(k -> k.getKey(), v -> v.getValue().toString()));
    }
}

2.3 demo

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Map;

/**
 * @describe:
 * @date 2025/9/30
 */
public class ValidatorDemo {
    
    @Data
    public static class  User{
        
        @NotNull
        private Integer userId;
        
        @NotEmpty
        private String username;
    }

    public static void main(String[] args) {
        User user = new User();
        Map<String,String> msg = ValidatorUtils.validate(user);
        System.out.println(msg);
    }
}

三、自定义校验规则(Validator)

3.1 自定义注解

import javax.validation.Constraint;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Documented
@Constraint(validatedBy = {NotEmptyValidator.class})
public @interface NotEmpty {
}

3.2 自定义校验器

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import org.apache.commons.lang3.StringUtils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Map;


/**
 * @describe:
 * @date 2025/9/30
 */
public class NotEmptyValidator  implements ConstraintValidator<NotEmpty, Object> {

    @Override
    public void initialize(NotEmpty constraintAnnotation) {
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
        if(ObjectUtil.isNull(value)){
            return false;
        }
        if (value instanceof String) {
            return StringUtils.isNotEmpty(value.toString());
        } else if (value instanceof Collection) {
            return !org.springframework.util.CollectionUtils.isEmpty((Collection) value);
        } else if (value instanceof Map) {
            return CollectionUtil.isNotEmpty((Map) value);
        } else if (value.getClass().isArray()) {
            return Array.getLength(value) > 0;
        }

        return false;
    }
}

3.3 demo

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Map;

/**
 * @author  
 * @describe:
 * @date 2025/9/30
 */
public class ValidatorDemo {

    @Data
    public static class  User{

        @NotNull
        private Integer userId;

        @NotEmpty
        private String username;
    }

    public static void main(String[] args) {
        User user = new User();
        Map<String,String> msg = ValidatorUtils.validate(user);
        System.out.println(msg);
    }
}

四、级联校验

4.1 校验的对象中包含另一个需要校验的对象

     使用@javax.validation.Valid  组合  @NotNull

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Map;

/**
 * @author
 * @describe:
 * @date 2025/9/30
 */
public class ValidatorDemo {

    @Data
    public static class  User{

        @NotNull
        private Integer userId;


        private String username;
//如果Dept为null,则无法校验,Dept.id,需要@NotNull组合
        @Valid
        @NotNull
        private Dept dept;
    }

    @Data
    public static class  Dept{

        @NotNull
        private Integer id;


        private String name;
    }


    public static void main(String[] args) {
        User user = new User();
        user.setUserId(1);
//        user.setDept(new Dept()); //如果Dept为null,则无法校验,Dept.id,需要@NotNull组合
        Map<String,String> msg = ValidatorUtils.validate(user);
        System.out.println(msg);
    }
}

五、分组校验(Validator)

5.1 工具类

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author 
 * @describe:
 * @date 2025/9/30
 */
public class ValidatorUtils {

    private static Validator validator = Validation.buildDefaultValidatorFactory()
            .getValidator();

    /**
     * 简单校验
     * @param obj
     * @return
     * @param <T>
     */
    public static <T> Map<String, String> validate(T obj) {
        Set<ConstraintViolation<T>> set = validator.validate(obj,  javax.validation.groups.Default.class);
        return convertErrorMap(set);
    }

    /**
     * 分组校验
     * @param obj
     * @param groups
     * @return
     * @param <T>
     */
    public static <T> Map<String, String> validate(T obj, Class<?>... groups) {
        Set<ConstraintViolation<T>> set = validator.validate(obj, groups);
        return convertErrorMap(set);
    }


    private static <T> Map<String, String> convertErrorMap(Set<ConstraintViolation<T>> set) {
        Map<String, StringBuilder> errorMap = new HashMap<>();
        if (set != null && set.size() > 0) {
            String property = null;
            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.entrySet().stream().collect(Collectors.toMap(k -> k.getKey(), v -> v.getValue().toString()));
    }


}

5.2 demo

package com.iync.dev.common.annotation;

public interface AddGroup {
}    
/**
* 接口参数体
*/
public class SyncConfSchoolInfo extends Model<SyncConfSchoolInfo> implements Serializable {

    private static final long serialVersionUID = 7311941644592730866L;
    /**
     * 自增ID
     */
    @NotNull(message = "id为空",groups = {AddGroup.class, UpdateGroup.class})
    @TableId(value = "ID", type = IdType.AUTO)
    private Long id;
    /**
     * 运营商标识
     */
    @TableField("OPERATOR_CODE")
    private String operatorCode;
}

/**
     * 状态控制
     * @param param
     * @return
     * @throws BusinessException
     */
    @PostMapping("/status")
    public RestResult updateStatus(@Validated(AddGroup.class)@RequestBody SyncConfSchoolInfo param) throws BusinessException {
        String reqUrl = request.getPathInfo();
        log.info(String.format("%s: %s start ", reqUrl, JSONObject.toJSONString(param)));
        Integer row = syncConfSchoolInfoService.updateStatus(param);
        log.info(String.format("%s:resp: %s end ", reqUrl, row));
        return RestResult.createSuccessfulResult(row);
    }

六、 Spring validator 方法级别的校验

JSR和Hibernate validator的校验只能对Object的属性进行校验,不能对单个的参数进行校验,spring 在此基础上进行了扩展,添加了MethodValidationPostProcessor拦截器,可以实现对方法参数的校验,实现如下:

6.1 实例化MethodValidationPostProcessor

@Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }

6.2 在所要实现方法参数校验的类上面添加@Validated,如下

@RestController
@Validated
public class ValidateController {
}

6.3 在方法上面添加校验规则:

@RequestMapping(value = "/test", method = RequestMethod.GET)
    public String paramCheck(@Length(min = 10) @RequestParam String name) {
        System.out.println(name);
        return null;
    }
 

参考:

相关链接资料
Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC https://my.oschina.net/qjx1208/blog/200946
Java Bean Validation 最佳实践 http://www.cnblogs.com/beiyan/p/5946345.html
 https://www.cnblogs.com/zhuhui-site/p/10088417.html
 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值