日常开发中经常会遇到需要参数校验的情况,比如某个字段不能为空、长度不能超过5等都属于参数校验的范围。对于简单的参数校验通过写几个if-else判断语句就搞定,但是对于复杂的多个参数校验的情况,就不是那么简单了,通常是各种循环嵌套+一堆if-else语句。一个字,丑!

所以,这就需要引进本文的主人公——Hibernate Validator(下文简称hb)。顾名思义,这是出自ORM框架Hibernate之手,那么,这个玩意可以帮助我们什么呢?

Express validation rules in a standardized way using annotation-based constraints and benefit from transparent integration with a wide variety of frameworks.

使用基于注解的约束,以标准化的方式表达验证规则,并可以与大多数框架无缝集成。

既然是基于注解进行阐述校验,那么有哪些注解呢?

参数注解

hv的参数校验有多个级别:

  1. bean
  2. method

bean也就是JavaBean(一个标准的)校验又有三种:

  • field constraints(字段)

  • property constraints(属性)

  • class constraints(类)

参数注解可以附加到字段、getter方法,类或者接口上面。对于一些特定的需求,用户可以很容易的开发定制化的约束。

hv提供了JSR规范中所有内置constraint的实现,除此之外还有一些附加的constraint。

快速入门

引入pom依赖:

        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
        </dependency>

        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.el</artifactId>
            <version>3.0.1-b08</version>
        </dependency>

        <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-validator</artifactId>
                <version>5.3.4.Final</version>
        </dependency>

JavaBean:

public class CarBO {

    @NotNull
    private String manufacturer;

    @NotNull
    @Size(min = 2, max = 5)
    private String licensePlate;

    @Min(5)
    private int seatCount;

    public CarBO(String manufacturer, String licencePlate, int seatCount) {
        this.manufacturer = manufacturer;
        this.licensePlate = licencePlate;
        this.seatCount = seatCount;
    }

    //setter、getter
}

编写测试类:

public class CarTest {
    private static Validator validator;

    @BeforeClass
    public static void setUp() {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        validator = factory.getValidator();
    }

    @Test
    public void manufacturerIsNull() {
        CarBO car = new CarBO( null, "DD-AB-123", 4 );

        Set<ConstraintViolation<CarBO>> constraintViolations =
                validator.validate( car );

        assertEquals( 1, constraintViolations.size() );
        assertEquals(
                "may not be null",
                constraintViolations.iterator().next().getMessage()
        );
    }

    @Test
    public void licensePlateTooShort() {
        CarBO car = new CarBO( "Morris", "D", 4 );

        Set<ConstraintViolation<CarBO>> constraintViolations =
                validator.validate( car );

        assertEquals( 1, constraintViolations.size() );
        assertEquals(
                "size must be between 2 and 14",
                constraintViolations.iterator().next().getMessage()
        );
    }

    @Test
    public void seatCountTooLow() {
        CarBO car = new CarBO( "Morris", "DD-AB-123", 1 );

        Set<ConstraintViolation<CarBO>> constraintViolations =
                validator.validate( car );

        assertEquals( 1, constraintViolations.size() );
        assertEquals(
                "must be greater than or equal to 2",
                constraintViolations.iterator().next().getMessage()
        );
    }

    @Test
    public void carIsValid() {
        CarBO car = new CarBO( "Morris", "DD-AB-123", 2 );

        Set<ConstraintViolation<CarBO>> constraintViolations =
                validator.validate( car );

        assertEquals( 0, constraintViolations.size() );
    }

}

在实际场景中,对于非法的参数需要抛出异常,比如哪个参数因为什么校验不通过。具体哪个字段可以通过ConstraintViolation的getPropertyPath方法获取,校验的提示信息可以通过ConstraintViolation的getMessage方法获取。

实例如下:

private void validate(CarBO car) {
        Set<ConstraintViolation<CarBO>> constraintViolations = validator.validate( car );
        if (!constraintViolations.isEmpty()) {
            throw new RuntimeException("参数非法!!" + getValidateMsg(constraintViolations));
        }
    }

    private String getValidateMsg(Set<ConstraintViolation<CarBO>> constraintViolations) {
        StringBuilder msg = new StringBuilder();
        for (ConstraintViolation<CarBO> violation : constraintViolations) {
            msg.append(violation.getPropertyPath())
                    .append(violation.getMessage())
                    .append(",");
        }
        return msg.substring(0, msg.lastIndexOf(","));
    }

Hibernate Validator参数校验的更多相关文章

  1. hibernate validator参数校验&自定义校验注解

    参数校验:简单的就逐个手动写代码校验,推荐用Valid,使用hibernate-validator提供的,如果参数不能通过校验,报400错误,请求格式不正确: 步骤1:在参数对象的属性上添加校验注解如 ...

  2. validator参数校验

    目录 validator参数校验 validator参数校验 type Req struct { Sn string `json:"sn" binding:"requir ...

  3. hibernate validator自定义校验注解以及基于服务(服务组)的校验

    hibernate validator是Bean Validation 1.1 (JSR 349) Reference Implementation,其广泛的应用在mvc的参数校验中,尤其是使用服务端 ...

  4. Hibernate Validator数据校验框架常用注释

    使用前先配置maven,加入依赖: <dependency> <groupId>org.hibernate</groupId> <artifactId> ...

  5. SpringBoot 2 快速整合 | Hibernate Validator 数据校验

    概述 在开发RESTFull API 和普通的表单提交都需要对用户提交的数据进行校验,例如:用户姓名不能为空,年龄必须大于0 等等.这里我们主要说的是后台的校验,在 SpringBoot 中我们可以通 ...

  6. SpringMVC--使用hibernate validator数据校验

    JSR 303 Spring3开始支持JSR 303 验证框架,JSR303是Java为Bean数据合法性校验所提供的标准框架.JSR 303 支持XML和注解风格的验证,通过在Bean属性上标注类似 ...

  7. validator 参数校验的常用注解

    @AssertFalse Boolean,boolean 验证注解的元素值是false @AssertTrue Boolean,boolean 验证注解的元素值是true @NotNull 任意类型 ...

  8. Java Bean Validation(参数校验) 最佳实践

    转载来自:http://www.cnblogs.com 参数校验是我们程序开发中必不可少的过程.用户在前端页面上填写表单时,前端js程序会校验参数的合法性,当数据到了后端,为了防止恶意操作,保持程序的 ...

  9. SpringBoot 参数校验的方法

    Introduction 有参数传递的地方都少不了参数校验.在web开发中,前端的参数校验是为了用户体验,后端的参数校验是为了安全.试想一下,如果在controller层中没有经过任何校验的参数通过s ...

随机推荐

  1. Codeforces 235C. Cyclical Quest

    传送门 写的时候挺蛋疼的. 刚开始的时候思路没跑偏,无非就是建个SAM然后把串开两倍然后在SAM上跑完后统计贡献.但是卡在第二个样例上就是没考虑相同的情况. 然后开始乱搞,发现会出现相同串的只有可能是 ...

  2. 20145302张薇《Java程序设计》实验四报告

    20145325张薇 实验四:Andoid开发基础 实验内容 使用 Android Studio 设计"Hello" 设计过程 首先创建项目 选择.xml中的`Design 选中W ...

  3. 修改Linux登录提示信息

    佛祖保佑式 cat >> /etc/profile.d/message.sh << END echo -e "\033[33;40;5m _ooOoo_ O88888 ...

  4. RabbitMQ脑裂

    在RabbitMQ3.4.x中会出现脑裂的现象,本文通过实验验证此脑裂现象,愿小伙伴们少走弯路. Preview 网上有两篇帖子(需要FQ) https://groups.google.com/for ...

  5. Linux命令:chmod、chgrp、chown的区别

    chmod是更改文件的权限: chgrp只是更改文件的属组: chown是更改文件的属主与属组. 1.chmod:更改文件的权限 文件权限的设置方式有两种,分别是数字和标记. mode : 权限设定字 ...

  6. c++之初级的消息队列及线程池模型

    1.最近项目不是很忙,结合之前看的一些开源代码(skynet及其他github代码)及项目代码,抽空写了一个简单的任务队列当做练习. 2.介绍: 1)全局队列中锁的使用:多线程下,全局队列需要加锁,本 ...

  7. SpringMvc 笔记

    整理出来是 SpringMvc 笔记 方便以后查询 框架太多了 不经常使用 忘记的可能性很大 自己整理一套笔记 一看就明白了 1 对比 原始请求响应流程 1 发送请求 --> 2 控制层 --& ...

  8. Gym - 100712H Bridges(边—双连通分量)

    https://vjudge.net/problem/Gym-100712H 题意: 给出一个图,求添加一条边后最少的桥数量. 思路: 参考了ZSQ大神的题解http://blog.csdn.net/ ...

  9. 浅谈C#泛型的定义、继承、方法和约束

    摘要:本文介绍了如何定义一个C#泛型类,以及实现泛型类的继承.方法和约束. C#泛型参数化了类型,把类型作为参数抽象出来,从而使我们在实际的运用当中能够更好的实现代码的重复利用,同时它提供了更强的类型 ...

  10. JAVA初学者(一)

    2015-12-15 21:26:17 刚学的java  做个总结: 1.构造函数没有返回值. 2.A对象调用Q的方法,Q方法里的变量就是A的变量 Fraction add(Fraction f) 在 ...