SpringBoot 2 校验框架-Hibernate框架

168 阅读7分钟

文档参考 hibernate.org/validator/d…

1.1 pom.xml 导入Hibernate

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

1.2 Applying constraints

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotNull;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
    private Integer id;
    @NotNull(message = "name cannot be null.")
    private String name;
    private Integer age;
}

1.3 Validating constraints

// 使用Errors 获取未通过校验的数据
@PutMapping("/updateUser")
public boolean updateUser(@RequestBody @Valid User user, Errors errors) {
    if (errors.hasErrors()) {
        List<FieldError> fieldErrors = errors.getFieldErrors();
        for (FieldError f : fieldErrors) {
            String field = f.getField();
            String errorMsg = f.getDefaultMessage();
            System.out.println(field + "----------" + errorMsg);
        }
    }
    System.out.println("updateUser: " + user);
    return true;
}

校验框架

1.1 校验框架入门

1.1.1 表单校验的重要性

  • 表单校验保障了数据有效性、安全性

数据可以随意输入,导致错误的结果。后端表单校验的重要性。

1.1.2 表单校验分类

  • 校验位置:
    • 客户端校验
    • 服务端校验
  • 校验内容与对应方式:
    • 格式校验
      • 客户端:使用Js技术,利用正则表达式校验
      • 服务端:使用校验框架
    • 逻辑校验
      • 客户端:使用ajax发送要校验的数据,在服务端完成逻辑校验,返回校验结果
      • 服务端:接收到完整的请求后,在执行业务操作前,完成逻辑校验

1.1.3 表单校验规则

  • 长度:例如用户名长度,评论字符数量
  • 非法字符:例如用户名组成
  • 数据格式:例如Email格式、 IP地址格式
  • 边界值:例如转账金额上限,年龄上下限
  • 重复性:例如用户名是否重复

1.1.4 表单校验框架

  • JSR(Java Specification Requests):Java 规范提案

    303:提供bean属性相关校验规则

  • JSR规范列表

    • 企业应用技术  Contexts and Dependency Injection for Java (Web Beans 1.0) (JSR 299)  Dependency Injection for Java 1.0 (JSR 330)@postConstruct, @PreDestroy  Bean Validation 1.0 (JSR 303)  Enterprise JavaBeans 3.1 (includes Interceptors 1.1) (JSR 318)  Java EE Connector Architecture 1.6 (JSR 322)  Java Persistence 2.0 (JSR 317)  Common Annotations for the Java Platform 1.1 (JSR 250)  Java Message Service API 1.1 (JSR 914)  Java Transaction API (JTA) 1.1 (JSR 907)  JavaMail 1.4 (JSR 919)
    • Web应用技术  Java Servlet 3.0 (JSR 315)  JavaServer Faces 2.0 (JSR 314)  JavaServer Pages 2.2/Expression Language 2.2 (JSR 245)  Standard Tag Library for JavaServer Pages (JSTL) 1.2 (JSR 52)  Debugging Support for Other Languages 1.0 (JSR 45)  模块化 (JSR 294)  Swing应用框架 (JSR 296)  JavaBeans Activation Framework (JAF) 1.1 (JSR 925)  Streaming API for XML (StAX) 1.0 (JSR 173)
    • 管理与安全技术  Java Authentication Service Provider Interface for Containers (JSR 196)  Java Authorization Contract for Containers 1.3 (JSR 115)  Java EE Application Deployment 1.2 (JSR 88)  J2EE Management 1.1 (JSR 77)  Java SE中与Java EE有关的规范  JCache API (JSR 107)  Java Memory Model (JSR 133)  Concurrency Utilitie (JSR 166)  Java API for XML Processing (JAXP) 1.3 (JSR 206)  Java Database Connectivity 4.0 (JSR 221)  Java Management Extensions (JMX) 2.0 (JSR 255)  Java Portlet API (JSR 286)
  • Web Service技术  Java Date与Time API (JSR 310)  Java API for RESTful Web Services (JAX-RS) 1.1 (JSR 311)  Implementing Enterprise Web Services 1.3 (JSR 109)  Java API for XML-Based Web Services (JAX-WS) 2.2 (JSR 224)  Java Architecture for XML Binding (JAXB) 2.2 (JSR 222)  Web Services Metadata for the Java Platform (JSR 181)  Java API for XML-Based RPC (JAX-RPC) 1.1 (JSR 101)  Java APIs for XML Messaging 1.3 (JSR 67)  Java API for XML Registries (JAXR) 1.0 (JSR 93)

  • JCP(Java Community Process):Java社区

  • Hibernate框架中包含一套独立的校验框架hibernate-validator

    导入坐标

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

springboot依赖:

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

注意: tomcat7 :搭配hibernate-validator版本5...Final tomcat8.5↑ :搭配hibernate-validator版本6...Final

1.2 快速使用

1. 开启校验

 名称:@Valid 、 @Validated  类型:形参注解  位置:处理器类中的实体类类型的方法形参前方  作用:设定对当前实体类类型参数进行校验  范例:

@PutMapping("/updateUser")
public boolean updatetUser(@RequestBody @Valid User user){
    System.out.println(user);
    return true;
}

2.设置校验规则

 名称:@NotNull  类型:属性注解 等  位置:实体类属性上方  作用:设定当前属性校验规则  范例: 每个校验规则所携带的参数不同,根据校验规则进行相应的调整 具体的校验规则查看对应的校验框架进行获取

@Data
@ApiModel(value = "用户",description = "用户描述类")
public class User {
    private Integer id;
    @NotNull(message = "姓名不能为null")
    private String name;
}

3.获取错误信息

    @PutMapping("/updateUser")
    public boolean updatetUser(@RequestBody @Valid User user, Errors errors){
        if (errors.hasErrors()) {
            List<FieldError> fieldErrors = errors.getFieldErrors();
            for (FieldError fieldError : fieldErrors) {
                //获取字段名称
                String field = fieldError.getField();
                //错误信息
                String errorMsg = fieldError.getDefaultMessage();
                System.out.println(field+"-----"+errorMsg);
            }
        }
        System.out.println(user);
        return true;
    }

通过形参Errors获取校验结果数据;

1.3 多规则校验

  • 同一个属性可以添加多个校验器
@NotNull(message = "请输入您的年龄")
@Max(value = 60,message = "年龄最大值不允许超过60岁")
@Min(value = 18,message = "年龄最小值不允许低于18岁")
private Integer age;//员工年龄
  • 3种判定空校验器的区别

image-20200506160725709.png

  • 其他校验注解

    @AssertFalse 验证注解的元素值是 false
    @AssertTrue 验证注解的元素值是 true
    @DecimalMax(value=x) 验证注解的元素值小于等于指定的十进制value值
    @DecimalMin(value=x) 验证注解的元素值大于等于指定的十进制value值
    @Digits(integer=整数位数, fraction=小数位数)验证注解的元素值的整数位数和小数位数上限
    @Future 验证注解的元素值(日期类型)比当前时间晚
    @Max(value=x) 验证注解的元素值小于等于指定的 value值
    @Min(value=x) 验证注解的元素值大于等于指定的 value值
    @NotNull 验证注解的元素值不是 null
    @Null 验证注解的元素值是 null
    @Past 验证注解的元素值(日期类型)比当前时间早
    @Pattern(regex=正则表达式) 验证注解的元素值不指定的正则表达式匹配
    @Size(min=最小值, max=最大值) 验证注解的元素值的在 min 和 max (包含)指定区间之内,如字符长度、集合大小
    @Valid 该注解主要用于字段为一个包含其他对象的集合或map或数组的字段,或该字段直接为一个其他对象的引用,这样在检查当前对象的同时也会检查该字段所引用的对象。
    @NotEmpty 验证注解的元素值不为 null 且不为空(字符串长度不为 0、集合大小不为 0)
    @Range(min=最小值, max=最大值)验证注解的元素值在最小值和最大值之间
    @NotBlank 验证注解的元素值不为空(不为 null、去
    除首位空格后长度为 0),不同于@NotEmpty, @NotBlank 只应用于字符串且在比较时会去除字符串的空格
    @Length(min=下限, max=上限) 验证注解的元素值长度在 min 和 max 区间内
    @Email 验证注解的元素值是 Email,也可以通过正则表达式和 flag 指定自定义的 email 格式
    

1.4 嵌套校验

 名称:@Valid  类型:属性注解  位置:实体类中的引用类型属性上方  作用:设定当前应用类型属性中的属性开启校验  范例:

@Data
@ApiModel(value = "用户",description = "用户描述类")
public class User {
    @NotNull(message = "id不能为空")
    private Integer id;
    @NotNull(message = "姓名不能为null")
    private String name;

    @NotNull(message = "请输入姓名")
    @Max(value = 60,message = "年龄最大值不允许超过60")
    @Min(value = 18,message = "年龄最小值为18")
    private Integer age;
    @Email
    private String email;
    @Valid//用于嵌套的对象的校验
    private Address address;
}

 注意:开启嵌套校验后,被校验对象内部需要添加对应的校验规则

1.5 分组校验

​ 但日常系统中对于不同模块可能对于同一字段合法性校验也会不同,例如用户(User)在注册时可能对于是否邮件填写敏感,而用户添加课程学习列表时也只对用户当前添加课程关心,这样我们之前统一的校验就不起作用了,而hibernate提供的分组功能就能帮助我们实现.直接上代码。

  • 同一个模块,根据执行的业务不同,需要校验的属性会有不同
    • 新增用户
    • 修改用户
  • 对不同种类的属性进行分组,在校验时可以指定参与校验的字段所属的组类别
    • 定义组(通用)
    • 为属性设置所属组,可以设置多个
    • 开启组校验

定义一个没有任何方法的接口:

public interface GroupOne {
}

在不同的校验规则中通过groups指定当前校验规则所属的分组:

@NotEmpty(message = "姓名不能为空",groups = {GroupOne.class})
private String name;//员工姓名

在controller控制方法中直接指定当前方法所属分组即可!

public String addEmployee(@Validated({GroupOne.class}) Employee employee){
}