在Spring中使用数据验证组件hibernate-validator

在做web开发的时候,经常需要对客户端发送过来的数据进行一个验证,以防数据不合法。

而SpringMVC支持的数据校验是JSR303的标准,通过在bean的属性上打上annotation @NotNull @Max等注解进行验证。JSR303提供有很多annotation借口,而SpringMVC对于这些验证是使用hibernate的实现,所以我们需要添加hibernate的一个validator包:

在SpringMVC中引入

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

在Springboot中引入

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

hibernate除了JSR303的标准之外还额外提供了其他的验证注解。下表是JSR303支持的验证注解:

约束注解名称 约束注解说明
@Null 验证对象是否为空
@NotNull 验证对象是否为非空
@AssertTrue 验证Boolean对象是否为true
@AssertFalse 验证Boolean对象是否为false
@Min 验证Number和String对象是否大等于指定的值
@Max 验证Number和String对象是否小等于指定的值
@DecimalMin 验证Number和String对象是否大等于指定的值,小数存在精度
@DecimalMax 验证Number和String对象是否小等于指定的值,小数存在精度
@Size 验真对象(Array, Collection, Map, String)长度是否在给定范围之内
@Digits 验证Number和String的构成是否合法
@Past 验证Date和Calendar对象是否在当前时间之前
@Future 验证Date和Calendar对象是否在当前时间之后
@Pattern 验证String对象是否符合正则表达式的规则

Hibernate Validator 附加的注解:

注解 详细信息
@Email 必须是电子邮箱地址
@Length 被注释的字符串的大小必须在指定范围之内
@NotEmpty 被注释的字符串必须是非空
@Range 被注释的元素必须在指定范围之内

下面我们来写个小demo,具体演示一下如何使用。例如,我要验证一些字段不能为空,那么就可以使用@NotNull这个注解,如下示例:

package org.zero01.test;

import javax.validation.constraints.NotNull;

public class UserRegister {

    @NotNull(message = "用户名不能为空")
    private String userName;
    @NotNull(message = "密码不能为空")
    private String password;
    @NotNull(message = "联系地址不能为空")
    private String address;
    @NotNull(message = "电话号码不能为空")
    private String phone;
    ...getter and setter...

在控制器的方法参数中,需要通过声明BindingResult参数来获得验证出错的信息,然后使用@Valid注解来配置哪个pojo对象需要校验,控制器代码如下:

package org.zero01.test;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.validation.Valid;

@Controller
public class Test {

    @RequestMapping(value = "/test.do", method = RequestMethod.GET)
    // 注意,@Valid和BindingResult是配对出现,并且形参顺序是固定的(一前一后),不然就会返回400状态码
    public String test(@Valid UserRegister userRegister, BindingResult bindingResult, Model model) {
        // 判断是否有异常
        if (bindingResult.hasErrors()) {
            System.out.println("客户端的请求数据异常,所有的异常如下:");
            // 取出所有的异常对象
            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                // 打印异常的字段以及异常信息
                System.out.println(fieldError.getField() + " : " + fieldError.getDefaultMessage());
            }
            return "register";
        }
        return "index";
    }
}

使用Postman进行访问,什么参数都不写

控制台输出结果如下:

客户端的请求数据异常,所有的异常如下:
address : 联系地址不能为空
userName : 用户名不能为空
password : 密码不能为空
phone : 电话号码不能为空

下面再来演示一下其他常用的注解:

package org.zero01.test;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

public class UserRegister {

    @NotNull(message = "用户名不能为空")
    private String userName;

    @NotNull(message = "密码不能为空")
    @Length(max = 12, min = 6, message = "密码长度需在6-12位之间")
    private String password;

    @NotNull(message = "联系地址不能为空")
    private String address;

    @NotNull(message = "电话号码不能为空")
    // 指定正则表达式验证格式
    @Pattern(regexp = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\\\d{8}$", message = "电话号码格式错误")
    private String phone;

    @Email(message = "邮箱格式错误")
    private String email;

    @Size(max = 10, min = 1, message = "成绩单列表长度需在1-10之间")
    public List resultList;
    ...getter and setter...

控制器代码和之前一致,略。

使用Postman进行访问

控制台输出结果如下:

客户端的请求数据异常,所有的异常如下:
address : 联系地址不能为空
userName : 用户名不能为空
password : 密码长度需在6-12位之间
phone : 电话号码格式错误
email : 邮箱格式错误
resultList : 成绩单列表长度需在1-10之间

以上我们都是对所有的字段进行验证,如果我希望有些字段不被验证或者分开验证该怎么办呢?这时候我们就需要到分组验证了,首先编写一个接口:

package org.zero01.test;

public interface Group {
}

然后在需要分组的字段上的注解中加上groups属性,该属性的值为以上我们所定义的接口类,如下示例:

package org.zero01.test;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

public class UserRegister {

    // groups 属性用于指定分组,值为一个接口类
    @NotNull(message = "用户名不能为空", groups = Group.class)
    private String userName;

    @NotNull(message = "密码不能为空", groups = Group.class)
    @Length(max = 12, min = 6, message = "密码长度需在6-12位之间", groups = Group.class)
    private String password;

    @NotNull(message = "联系地址不能为空")
    private String address;

    @NotNull(message = "电话号码不能为空")
    @Pattern(regexp = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\\\d{8}$", message = "电话号码格式错误")
    private String phone;

    @Email(message = "邮箱格式错误")
    private String email;
    ...getter and setter...

控制器代码如下:

package org.zero01.test;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.validation.Valid;

@Controller
public class Test {

    @RequestMapping(value = "/test.do", method = RequestMethod.GET)
    // 分组的情况下需要使用Validated注解来指定接口
    public String test(@Validated(Group.class) UserRegister userRegister, BindingResult bindingResult, Model model) {

        if (bindingResult.hasErrors()) {
            System.out.println("客户端的请求数据异常,所有的异常如下:");

            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                System.out.println(fieldError.getField() + " : " + fieldError.getDefaultMessage());
            }
            return "register";
        }
        return "index";
    }
}

访问方式和之前一致,略。

控制台输出结果如下:

客户端的请求数据异常,所有的异常如下:
password : 密码长度需在6-12位之间
userName : 用户名不能为空

如上,从控制台的打印结果中,可以看到只有password以及userName两个字段受到了验证,这是因为我们只在这两个字段上的注解中指定了groups 属性。所以分组验证就是只验证指定组的字段,而这个组的划分是以接口来划分的。

站在巨人的肩膀上摘苹果:

https://blog.51cto.com/zero01/2090999

原文地址:https://www.cnblogs.com/eternityz/p/12442673.html

时间: 2024-10-08 18:08:39

在Spring中使用数据验证组件hibernate-validator的相关文章

在SpringMVC中使用数据验证组件——hibernate-validator

在做web开发的时候,经常需要对客户端发送过来的数据进行一个验证,以防数据不合法.而SpringMVC支持的数据校验是JSR303的标准,通过在bean的属性上打上annotation @NotNull @Max等注解进行验证.JSR303提供有很多annotation借口,而SpringMVC对于这些验证是使用hibernate的实现,所以我们需要添加hibernate的一个validator包: <dependency> <groupId>org.hibernate</g

容器扩展属性 IExtenderProvider 实现WinForm通用数据验证组件

大家对如下的Tip组件使用应该不陌生,要想让窗体上的控件使用ToolTip功能,只需要拖动一个ToolTip组件到窗口,所有的控件就可以使用该功能,做信息提示. 本博文要记录的,就是通过容器扩展属性 IExtenderProvider,来实现一个数据验证组件,通过将组件拖动到窗口后,使得上面的所有控件可以实现数据验证! 设置下面两个扩展属性,即可使用组件 调用开放的验证方法public bool VerifyData(Control ct = null)后,验证样式为: 1.实现思路: 通过记录

自定义react数据验证组件

我们在做前端表单提交时,经常会遇到要对表单中的数据进行校验的问题.如果用户提交的数据不合法,例如格式不正确.非数字类型.超过最大长度.是否必填项.最大值和最小值等等,我们需要在相应的地方给出提示信息.如果用户修正了数据,我们还要将提示信息隐藏起来. 有一些现成的插件可以让你非常方便地实现这一功能,如果你使用的是knockout框架,那么你可以借助于Knockout-Validation这一插件.使用起来很简单,例如我下面的这一段代码: ko.validation.locale('zh-CN');

在kettle中实现数据验证和检查

在kettle中实现数据验证和检查 在ETL项目,输入数据通常不能保证一致性.在kettle中有一些步骤能够实现数据验证或检查.验证步骤能够在一些计算的基础上验证行货字段:过滤步骤实现数据过滤:javascript步骤能够实现更复杂的计算. 通常以某种方式查看那些数据是有缺陷的也是实用的,由于大多数ETL是无人值守执行的,所以通常ETL程序会把这些缺陷数据通知给ETL开发人员或管理员.建议把这些问题数据行保存到一个特定的公共表格中,以便跟踪这些数据:那么该表格应该包含一些元信息,如:执行转换的名

用spring的@Validated注解和org.hibernate.validator.constraints.*的一些注解在后台完成数据校验

这个demo主要是让spring的@Validated注解和hibernate支持JSR数据校验的一些注解结合起来,完成数据校验.这个demo用的是springboot. 首先domain对象Foo的代码如下: package com.entity; import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.NotBlank; import javax.validati

MVC中的数据验证

一  概述 关于数据验证和数据注解,是任何软件系统不可小觑的必要模块,在软件系统中起到举足轻重的作用,主要作用是为了保证数据安全性.防止漏洞注入和网络攻击. 从数据验证的验证方式来说,我们一般分为客户端验证和服务端验证(或者两种方式相结合),本篇文章主要讲解基于ASP.NET MVC框架的数据验证特性和数据注解. 二  数据验证 (一)ASP.NET MVC 内置六大类数据验证特性 在ASP.NET MVC中,验证特性定义在 System.ComponentModel.DataAnnotatio

[原理][源代码解析]spring中@Transactional,Propagation.SUPPORTS,以及 Hibernate Session,以及jdbc Connection关系---转载

问题: 一. 1. Spring 如何处理propagation=Propagation.SUPPORTS? 2. Spring 何时生成HibernateSession ? 3. propagation=Propagation.SUPPORTS 和propagation=Propagation.require对生成Session有何影响 ? 共同点:都会进入aspect切面处理, 试图新建Session,开启Transaction ,都能获得.TransactionStatus 区别: 前者成

在spring中使用邮箱验证

当我们进行注册或是密码找回,等某种情景的时候,可以通过邮箱发送验证码,进确认账号等操作. SMTP是一种有效且可靠的简单邮件传输协议,主要用于传输系统之间的邮件信息的传送.邮件发送协议. 163邮箱 :  smtp.163.com   qq邮箱:smtp.qq.com POP3是TCP/IP协议中的一员,主要用于支持使用客户端远程管理在服务器上的电子邮件.提供了SSL加密的POP3协议被称为POP3S.邮件接收协议. 需要导入的jar包 1 <!-- 邮件支持 --> 2 <depend

spring mvc @Valid 数据验证

//对书的单价校验不能是空,价格在20-100之间   @DecimalMax(value = "100", message = "价格不超过100元")   @DecimalMin(value = "20",message = "价格不低于20元") @Pattern(regexp = "1[345678][0-9]{9}",message = "手机号不符合规格") @IDValid