Java后端数据校验学习总结

news2025/1/19 11:35:13

Java后端校验总结

后端校验注解一直在用,但是感觉不是特别清楚,希望通过写这篇文章搞清楚。

Spring自带的Validation校验框架

Spring提供了Validator接口来校验对象,主要涉及到的方法和类如下:

  1. supports方法:设置校验器能对哪些对象进行校验;
  2. validate方法:对要校验的对象进行校验,并将校验错误记录在errors中;
  3. Errors类:用来存放错误信息的接口。Errors对象包含一系列的FieldError和ObjectError对象。FieldError表示与被获取的对象中的某一属性相关的一个错误;
  4. ValidationUtils:校验工具类,提供多个给Errors对象保存错误的方法;LocalValidatorFactoryBean:该类实现了Spring的Validator接口,也实现了JSR 303的Validator接口;
  5. BeanValidationPostProcessor:它就是个普通的BeanPostProcessor。它能够去校验Spring容器中的Bean,从而决定允不允许它初始化完成;
    1、

示例代码

实体类

public class MyUser implements Serializable {

    private String username;

    private Integer age;


    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", age=" + age +
                '}';
    }
}

UserValidator


/**
 * 用户数据校验类
 */
@Component
public class UserValidator implements Validator {

    /**
     * 对哪个类进行校验,此处仅对User类进行校验
     * @param clazz
     * @return
     */
    @Override
    public boolean supports(Class<?> clazz) {
        return User.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        //对name进行校验
        ValidationUtils.rejectIfEmpty(errors, "username", "500", "name is empty");

        MyUser user = (MyUser) target;
        if (user.getAge() < 0) {
            //
            errors.rejectValue("age", "500", "年龄不能小于0");
        }
    }
}

Controller中的代码

    @Autowired
    private UserValidator userValidator;

    @RequestMapping("/test3")
    public void test1(MyUser user, Errors errors) {
        userValidator.validate(user, errors);
        if (errors.hasErrors()) {
            //如果校验出错,输出错误信息
            List<ObjectError> allErrors = errors.getAllErrors();
            for (ObjectError error : allErrors) {
                System.out.println("test1 error " + error.getCode() + " " + error.getDefaultMessage());
            }
        }
    }

JSR303

JSR 303是Java为Bean数据合法性校验提供的标准框架,已经包含在Java EE 6.0中。JSR是一个规范,它的核心接口是Validator,该接口根据目标对象类中所标注的校验注解进行数据校验,并得到校验结果。
JSR303包含的注解如下:
在这里插入图片描述

示例代码

BindingResult:BindingResult扩展了Errors接口,同时可以获取数据绑定结果对象的信息。@Valid和BindingResult参数是成对出现的,并且在形参中出现的顺序是固定的,一前一后。


public class MyUser implements Serializable {

    @NotNull(message = "username is empty")
    @NotEmpty(message = "username is empty")
    private String username;

    @NotNull(message = "age is empty")
    @Max(value = 150L, message = "年龄最大为150")
    @Min(value = 0L, message = "年龄最小为0")
    private Integer age;


    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", age=" + age +
                '}';
    }
}
    @RequestMapping("/test4")
    public void test4(@Valid MyUser myUser, BindingResult result) {
        if (result.hasErrors()) {
            List<ObjectError> allErrors = result.getAllErrors();
            for (ObjectError error : allErrors) {
                System.out.println("error: " + error.getCode() + " " + error.getDefaultMessage());
            }
        }
    }

方法级别的参数校验

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

1、注入Bean

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

2、在controller上添加@Validated注解
在这里插入图片描述

3、方法参数上加上注解校验

    @RequestMapping("/test5")
    public void test5(@NotNull(message = "username is empty")  @NotEmpty(message = "username is empty")
                                   @RequestParam String username, @NotNull(message = "age is empty") @Max(value = 150L, message = "年龄最大为150")
                                    @Min(value = 0L, message = "年龄最小为0") @RequestParam  Integer age) {
        System.out.println("username: " + username + " age: " + age);
    }

分组校验

1、定义两个分组

public interface MyUserAddVo {
}


public interface MyUserUpdateVo {
}

2、指定分组,age属性的@NtoNull注解指定了MyUserAddVo.class, MyUserUpdateVo.class两个分组,而@Min指定了一个分组

public class MyUser implements Serializable {

    @NotNull(groups = {MyUserAddVo.class, MyUserUpdateVo.class}, message = "username is empty")
    @NotEmpty(groups = {MyUserAddVo.class, MyUserUpdateVo.class}, message = "username is empty")
    private String username;

    @NotNull(groups = {MyUserAddVo.class, MyUserUpdateVo.class}, message = "age is empty")
    @Max(groups = {MyUserAddVo.class, MyUserUpdateVo.class}, value = 150L, message = "年龄最大为150")
    @Min(groups = {MyUserAddVo.class}, value = 0L, message = "年龄最小为0")
    private Integer age;


    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", age=" + age +
                '}';
    }
}

3、在Controller中具体指定使用哪个分组的校验,代码中指定使用MyUserUpdateVo分组

    /**
     * 备注:此处@Validated(PersonAddView.class) 表示使用PersonAndView这套校验规则,若使用@Valid 则表示使用默认校验规则,
     *若两个规则同时加上去,则只有第一套起作用
     *
     **/
    @RequestMapping("/test6")
    public void test6(@Validated({MyUserUpdateVo.class}) MyUser myUser) {
        System.out.println("username: " +  myUser.getUsername() + " age: " + myUser.getAge());
    }

@Valid和@Validated注解的区别

这两个注解都是进行数据校验的标志,区别如下:

  1. @Valid是JSR-303标准规定的;@Validated是Spring校验框架提供的;
  2. @Valid可以在方法/成员变量/构造函数/方法参数上使用;@Validated可以在类/方法/方法参数上使用;区别在于成员变量上是否可以使用;由于@Valid可以在成员变量上使用,因此可以嵌套校验;
  3. @Valid会把校验不通过的信息交给BindingResult中,因此在controller的方法中,@Valid和BindingResult要同时存在;
  4. @Validated可以在类上使用;可以配合MethodValidationPostProcessor实现校验基本数据包装类型和String类型等单独的对象

参考

  • 详述Spring对Bean Validation支持的核心API:Validator、SmartValidator、LocalValidatorFactoryBean…【享学Spring】
  • 《SpringMVC+MyBatis快速开发与项目实战 》
  • Spring数据校验(LocalValidatorFactoryBean和MethodValidationPostProcessor的区别/@Valid和@Validated的区别)
  • Java Bean Validation 最佳实践

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/197615.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

win11任务栏图标闪烁|任务栏QQ图标闪动|新消息任务栏自动弹出|设置自动隐藏任务栏之后,QQ或微信等工具新消息自动弹出任务栏并颜色提示问题解决方案

背景介绍: 今天正常使用电脑时也出现消息弹出问题(已经设置隐藏任务栏),很头疼那么时什么情况,该如何组去解决呢?(微信任务栏闪动未读消息) MyDockFinder Windows 桌面美化工具 目录 背景介绍 解决问题 微信环境测试 初始界面&#xff08;微信&#xff09; 打开微信 …

PostMan简介2022黑马跟学

2022黑马PostMan简介跟学1.PostMan工具的使用1.1 PostMan简介1.2 PostMan安装1.3 PostMan使用1.3.1 创建WorkSpace工作空间1.3.2 发送请求(1).以百度为例发送get请求(2).以百度为例发送post请求1.3.3 保存当前请求1.3.4 创建server端1.PostMan工具的使用 1.1 PostMan简介 代码…

运算放大电路(三)-加法器

加法器 由虚短知&#xff1a; V- V 0 ……a 由虚断及基尔霍夫定律知&#xff0c;通过R2与R1的电流之和等于通过R3的电流&#xff0c;故 (V1 – V-)/R1 (V2 – V-)/R2 (Vout – V-)/R3 ……b 代入a式&#xff0c;b式变为 V1/R1 V2/R2 Vout/R3 如果取 R1R2R3 则上式变为 Vo…

ideal整合reids实现缓存查询

目录 前言&#xff1a; 一.工作流程 二. RedisConfig类 三.application.properties 四.开启linux中的redis 五.使用redis结合数据库进行数据查询 5.1编程式缓存 5.2声明式缓存 5.2.1在启动类上添加注解 5.2.2实现代码 六.运行结果 ​编辑 前言&#xff1a; 废话不多讲…

Java文件读写和CSV文件解析(读取csv文件的一列或若干列)

文件类 Java 读文件流的知识不可少&#xff0c;先复习一下吧&#xff01; OREACLE JDK8 DOCS 文件类是Java IO的一个对象&#xff0c;用于指定文件的相关信息&#xff0c;位置和名称信息。如txt文件&#xff0c;csv文件对Java来说就是一个文件类。 开发手册中指出&#xff0…

Android实战场景 - 保存WebView中的图片到相册

去年同事写了一个 “在H5中保存图片到相册” 的功能&#xff0c;虽然有大致实现思路&#xff0c;实现起来也没问题&#xff0c;但是感觉同事考虑问题的很周全&#xff0c;当时候就想着去学习一下&#xff0c;但是项目太赶没顾得上&#xff0c;索性现在有时间&#xff0c;准备好…

2023-02-01 读书笔记:《有趣的统计》-1-基础知识

2023-02-01 读书笔记&#xff1a;《有趣的统计》-1-基础知识 75招学会数据分析 —— 2014 Doctor.Bruce Frey 序 统计学&#xff1a; 最初&#xff0c;用于确定某些事情发生的可能性&#xff1b;不断发展&#xff0c;根据样本数据准确推断总体数据特征的方法&#xff08;推…

c语言基础之分支和循环语句

c语言基础之分支和循环语句分支语句和循环语句什么是语句&#xff1f;if语句switch语句在switch语句中的 breakwhile循环while语句中的break和continuefor循环break和continue在for循环中do...while()循环goto语句写在最后&#xff1a;&#x1f4cc;————本章重点————&a…

全球疫情期间的校园招聘:可以学到的6个教训

疫情放开后&#xff0c;校园招聘逐渐回暖&#xff0c;谁能率先有效整合线上线下校招&#xff0c;企业将从一开始就处于战略领先地位。下面梳理了全球招聘团队在疫情期间的6个校招教训&#xff0c;希望对你有启发。01重新规划线上工具的应用玩法现如今&#xff0c;学生已通过网课…

【C++提高编程】vector容器详解(附测试用例与结果图)

目录1.vector容器1.1 vector基本概念1.2 vector构造函数1.3 vector赋值操作1.4 vector容量和大小1.5 vector插入和删除1.6 vector数据存取1.7 vector互换容器1.8 vector预留空间1.vector容器 1.1 vector基本概念 功能&#xff1a; vector数据结构和数组非常相似&#xff0c;…

【C++】类和对象(上)

文章目录1. 面向过程和面向对象的初步认识2. 类的引入3. 类的定义4. 类的访问限定符及封装4.1 访问限定符4.2 封装5. 类的作用域6. 类的实例化7. 类对象模型7.1 如何计算对象的大小7.2 类对象的存储方式7.3 结构体内存对齐规则8. this指针8.1 this指针的引出8.2 this指针的特性…

性能技术分享|Jmeter+InfluxDB+Grafana搭建性能平台(二)

二、CentOS安装&#xff1a;方式一&#xff1a;把下载的.rpm包推送到服务器上&#xff1b;方式二&#xff1a;直接命令行安装#下载wget https://dl.influxdata.com/influxdb/releases/influxdb-1.7.1.x86_64.rpm#安装yum localinstall?influxdb-1.7.1.x86_64.rpm -y2.3 修改配…

三十一、RabbitMQ(2)

&#x1f33b;&#x1f33b; 目录一、RabbitMQ 入门及安装1.1 概述1.3 Erlang 安装1.2.1 安装下载1.2.3 安装依赖环境1.2.4 安装 Erlang1.2.4 Erlang安装成功1.3 安装 RabbitMQ1.5启动 rabbitmq 服务1.4 开启管理界面及配置1.5.1 设置配置文件二、RabbitMQWeb 管理界面及授权操…

【JVM】垃圾回收算法与分代回收

文章目录1. 垃圾回收算法概述2. 标记-清除算法3. 标记-复制算法4. 标记-整理算法5. 分代回收本文参考&#xff1a;深入理解Java虚拟机&#xff1a;JVM高级特性与最佳实践&#xff08;第3版&#xff09; 1. 垃圾回收算法概述 根据判定对象消亡的角度来看&#xff0c;垃圾收集算…

基于PHP的学院社团管理系统

摘 要“互联网”的战略实施后&#xff0c;很多行业的信息化水平都有了很大的提升。但是目前很多学校日常工作仍是通过人工管理的方式进行&#xff0c;需要在各个岗位投入大量的人力进行很多重复性工作&#xff0c;这样就浪费了许多的人力物力&#xff0c;工作效率较低&#xff…

Python爬虫4-Scrapy爬虫框架入门了解

目录1、Scrapy爬虫框架介绍1.1 requests库和Scarpy爬虫的比较1.2 Scrapy爬虫的常用命令2、Scrapy爬虫基本使用2.1 步骤2.2 yield关键字的使用1、Scrapy爬虫框架介绍 安装Scrapy库&#xff1a;pip install scrapy 爬虫框架&#xff1a;是实现爬虫功能的一个软件结构和功能组件集…

手动挂载apex镜像

手动挂载apex镜像 1.loop设备 在类 UNIX 系统里&#xff0c;loop 设备是一种伪设备(pseudo-device)&#xff0c;或者也可以说是仿真设备。它能使我们像块设备一样访问一个文件。 这要先从mount的流程来理解&#xff0c;挂载操作&#xff0c;实际上就是把设备上的文件系统/目…

【MyBatis】核心配置文件,三大对象的作用域,#{}和${}的区别

1. environment环境:一般一个环境environment会对应一个SqlSessionFactory对象sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"),"另一个环境的id");// 数据库环境配置在这个标签里 // 这里的default表示默认使用的环…

Spring Security 源码解读 :基本架构及初始化

Spring Security 是基于web的安全组件&#xff0c;所以一些相关类会分散在 spring-security包和web包中。Spring Security通过自定义Servlet的Filter的方式实现&#xff0c;具体架构可参考官网Spring Security: Architecture 这里使用Spring Boot 2.7.4版本&#xff0c;对应Sp…

安某客滑块分析

本文仅供学习&#xff0c;不参与商业应用 目标连接&#xff1a; aHR0cHM6Ly93d3cuYW5qdWtlLmNvbS9jYXB0Y2hhLXZlcmlmeS8/Y2FsbGJhY2s9c2hpZWxkJmZyb209YW50aXNwYW0 接口分析 刷新链接可以看到getInfoTp的接口&#xff0c;请求参数sessionId及dInfo是加密参数 返回的参数包含…