Spring下使用Beanvaildator

参数校验是我们程序开发中必不可少的过程。用户在前端页面上填写表单时,前端js程序会校验参数的合法性,当数据到了后端,为了防止恶意操作,保持程序的健壮性,后端同样需要对数据进行校验。后端参数校验最简单的做法是直接在业务方法里面进行判断,当判断成功之后再继续往下执行。但这样带给我们的是代码的耦合,冗余。当我们多个地方需要校验时,我们就需要在每一个地方调用校验程序,导致代码很冗余,且不美观。
那么如何优雅的对参数进行校验呢?JSR303就是为了解决这个问题出现的,本篇文章主要是介绍 JSR303,Hibernate Validator 等校验工具的使用,以及自定义校验注解的使用。

Pom.xml

<dependency>
  <groupId>javax.validation</groupId>
  <artifactId>validation-api</artifactId>
  <version>1.1.0.Final</version>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-validator</artifactId>
  <version>5.2.4.Final</version>
</dependency>

工具类BeanValidator .java

public class BeanValidator {


    private static ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();


    public static <T> Map<String, String> validate(T t, Class... groups) {
        //通过工厂类创建
        Validator validator = validatorFactory.getValidator();
        //自动获取校验的结果  validate是校验的方法
        Set validateResult = validator.validate(t, groups);
        if (validateResult.isEmpty()) {
            //无错结果
            return Collections.emptyMap();
        } else {
            LinkedHashMap errors = Maps.newLinkedHashMap();
            //通过迭代器获取每次校验的结果
            Iterator iterator = validateResult.iterator();
            while (iterator.hasNext()) {
                //ConstraintViolation 就是所谓的校验结果
                ConstraintViolation violation = (ConstraintViolation)iterator.next();
                //参数(字段,错误信息)
                errors.put(violation.getPropertyPath().toString(), violation.getMessage());
            }
            return errors;
        }
    }


    /**
     *
     * @param collection
     * @return
     */
    public static Map<String, String> validateList(Collection<?> collection) {
        //判断collection是否为空
        Preconditions.checkNotNull(collection);
        //
        Iterator iterator = collection.iterator();
        Map errors;


        do {
            if (!iterator.hasNext()) {
                return Collections.emptyMap();
            }
            Object object = iterator.next();
            errors = validate(object, new Class[0]);
        } while (errors.isEmpty());


        return errors;
    }


    /**
     * 当判断一个参数是否合法时 调用object,然后这个方法根据参数类型调用不同方法
     * @param first
     * @param objects
     * @return
     */
    public static Map<String, String> validateObject(Object first, Object... objects) {
        if (objects != null && objects.length > 0) {
            return validateList(Lists.asList(first, objects));
        } else {
            return validate(first, new Class[0]);
        }
    }


    public static void check(Object param) throws ParamException {
        Map<String, String> map = BeanValidator.validateObject(param);
        if (MapUtils.isNotEmpty(map)) {
            throw new ParamException(map.toString());
        }
    }
}

校验的实体类

@Getter
@Setter
public class TestVo {


    @NotBlank
    private String msg;


    @NotNull(message = "id不可以为空")
    @Max(value = 10, message = "id 不能大于10")
    @Min(value = 0, message = "id 至少大于等于0")
    private Integer id;

    //判断String类型用blank 判断数组类型用empty
    private List<String> str;
}

Controller

@RequestMapping("/validate.json")
    @ResponseBody
    public JsonData validate(TestVo vo) throws ParamException{
        BeanValidator.check(vo);
        return JsonData.success("test validate");
    }

原理:
当参数从前台传过来,是testvo的实体类,然后因为我在testvo的实体类针对参数设置了条件,比如id,这里设置的是不可为空,不可以大于十,不可以小于零。
然后controller,调用beanvalidator的check方法,开始检测,然后check方法调用自身的validateobject方法判断这是单个对象还是数组类型的,分别调用不同的判断方法去进行判断,最后返回结果。

其中可以使用的校验注解
在这里插入图片描述

PS:这里部分用到了lombok插件,如果test的时候报错,大家可以百度下lombok怎么使用!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值