java spring validation 自动、手动校验

news2024/9/27 9:21:18

目录

一、自动校验

第一步,导入依赖

第二步,统一异常处理

第三步,定义接口接收实体DTO

第四步,在Contoller接口中增加参数注解@Validated

第五步,测试结果

二、手动校验

第一步,校验工具类

第二步,测试结果


参数校验是一个常见的问题,比如字段非空,字段长度限制,邮箱格式、手机格式验证等等。

避免校验规则,写一大串步骤,繁琐重复。

Hibernate Validator为此提供了一套比较完善、便捷的验证实现方式。

一、自动校验

第一步,导入依赖

项目已经引入spring-boot-starter-web包里面有hibernate-validator包,不需要引用hibernate validator依赖。

项目还未引入spring-boot-starter-web包可以引入以下依赖:

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

第二步,统一异常处理

ValidateExceptionController

import com.central.common.model.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.Map;

/**
 * 统一异常处理
 */
@Slf4j
@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ValidateExceptionController {

    //如果能精确匹配到该异常就会执行这个方法,后续执行下面的方法
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result handelValidateException(MethodArgumentNotValidException e) {
        log.error("数据校验出现问题:{},异常类型:{}", e.getMessage(), e.getClass());
        Map<String, String> map = new HashMap<>();
        //1.获取校验错误结果
        BindingResult result = e.getBindingResult();
        result.getFieldErrors().forEach(fieldError -> {
            //获取每个错误的属性名字
            String field = fieldError.getField();
            //获取每个错误提示信息
            String defaultMessage = fieldError.getDefaultMessage();
            map.put(field, defaultMessage);
        });
        return Result.failed(map, "数据校验错误");
    }

}
第三步,定义接口接收实体DTO

定义校验规则,可以参考

Java Validation (验证注解)-CSDN博客

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List;

@Data
@ApiModel("售后申请接口-接收实体DTO")
public class AfterServiceApplyDTO implements Serializable {

    @NotBlank(message = "订单编号不为空")
    @ApiModelProperty(value = "订单编号", required = true)
    private String grandsonOrderCode;

    @NotNull(message = "申请售后类型不为空")
    @ApiModelProperty(value = "申请售后类型: 10:退货 20:换货 30:维修", required = true)
    private Integer customerExpect;

    @NotBlank(message = "产品问题描述不为空")
    @ApiModelProperty(value = "产品问题描述", required = true)
    private String questionDesc;

    @ApiModelProperty("问题描述图片链接地址,多个图片以“,”分隔")
    private String questionPic;

    @Valid
    @NotNull(message = "客户信息实体不为空")
    @ApiModelProperty("客户信息实体")
    private AfterSaleCustomerDTO asCustomerDto;

    @Valid
    @Size(min = 1, max = 1, message = "只能申请1个商品")
    @NotNull(message = "申请单明细列表不为空")
    @ApiModelProperty("申请单明细列表")
    private List<AfterSaleDetailDTO> asDetailDtos;


}
第四步,在Contoller接口中增加参数注解@Validated

表示只校验当前参数

@Api(tags = "【售后】订单售后API接口")
@RestController
public class AfterServiceApiController {

    /**
     * 售后申请接口
     * @param afterServiceApplyDTO 售后申请参数
     * @return 操作结果
     */
    @ApiOperation("售后申请接口")
    @PostMapping("/afterService/api/apply")
    public Result apply(@Validated @RequestBody AfterServiceApplyDTO afterServiceApplyDTO) {
        // todo
        return null;
    }

}
第五步,测试结果

Postman发送错误数据触发验证测试

二、手动校验

第一步,校验工具类

ValidatorUtils

import com.central.business.afterService.dto.AfterServiceApplyDTO;
import com.central.common.model.Result;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 校验工具类
 */
public class ValidatorUtils {

    private static final Validator validator;

    // 第一种方式创建Validator
    static {
        // 普通模式(默认是这个模式)
        // 普通模式(会校验完所有的属性,然后返回所有的验证失败信息)
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    //第二种方式创建Validator
//    static {
//        // 1.普通模式(默认是这个模式)
//        // 普通模式(会校验完所有的属性,然后返回所有的验证失败信息)
//        // .failFast(false)
//        // 或 .addProperty("hibernate.validator.fail_fast", "false")
//
//        // 2.快速失败返回模式
//        // 快速失败返回模式(只要有一个验证失败,则返回)
//        // .addProperty("hibernate.validator.fail_fast", "true")
//        // 或 .failFast(true)
//        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
//                .configure()
//                .failFast(true)
//                .buildValidatorFactory();
//        validator = validatorFactory.getValidator();
//    }

    /**
     * 校验对象,返回校验失败List信息
     *
     * @param object 对象
     * @param groups 组
     * @return 校验失败List信息
     */
    public static List<String> validateEntity(Object object, Class<?>... groups) {
        List<String> list = new ArrayList<>();

        Set<ConstraintViolation<Object>> validate = validator.validate(object, groups);
        for (ConstraintViolation<Object> violation : validate) {
            list.add(violation.getMessage());
        }
        return list;
    }

    /**
     * 校验对象,返回校验失败Map信息
     *
     * @param object 对象
     * @param groups 组
     * @return 校验失败Map信息,key为属性(字段名),value为校验失败信息
     */
    public static Map<String, String> validateEntityProperty(Object object, Class<?>... groups) {
        Map<String, String> map = new HashMap<>();

        Set<ConstraintViolation<Object>> validate = validator.validate(object, groups);
        for (ConstraintViolation<Object> violation : validate) {
            map.put(violation.getPropertyPath().toString(), violation.getMessage());
        }
        return map;
    }

    /**
     * 校验对象,返回校验失败Result信息
     *
     * @param object 对象
     * @param groups 组
     * @return 校验失败Result,校验失败返回错误信息,成功返回成功信息
     */
    public static Result<Map<String, String>> validateEntityResult(Object object, Class<?>... groups) {
        Map<String, String> map = new HashMap<>();

        Set<ConstraintViolation<Object>> validate = validator.validate(object, groups);
        for (ConstraintViolation<Object> violation : validate) {
            map.put(violation.getPropertyPath().toString(), violation.getMessage());
        }

        if (map.size() > 0) {
            return Result.failed(map, "数据校验错误!");
        }

        return Result.succeed("数据校验成功!");
    }

    public static void main(String[] args) {
        AfterServiceApplyDTO afterServiceApplyDTO = new AfterServiceApplyDTO();
        System.out.println(validateEntityResult(afterServiceApplyDTO));
    }
}
第二步,测试结果
Result(datas={questionDesc=产品问题描述不为空, grandsonOrderCode=供应链三级订单编号不为空, reason=售后原因不为空, asCustomerDto=客户信息实体不为空, asDetailDtos=申请单明细列表不为空, businessPlatformCode=业务商城售后申请单号不为空, customerExpect=申请售后类型不为空}, resp_code=1, resp_msg=数据校验错误!)

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

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

相关文章

Protubuf入门

⼀、初识 ProtoBuf 1. 序列化概念 序列化和反序列化 序列化&#xff1a;把对象转换为字节序列的过程 称为对象的序列化。 反序列化&#xff1a;把字节序列恢复为对象的过程 称为对象的反序列化。 什么情况下需要序列化 存储数据&#xff1a;当你想把的内存中的对象状态…

Spring Boot环境下的读书笔记交流网络

第2章 技术介绍 2.1B/S架构 当向其他用户发送请求的功能时应用B/S模式具有独一无二的优点&#xff1a;用户请求通过网络向其他Web服务器发送时只需要通过浏览器就可以实现该功能。该功能的好处之一就是有效简化了客户端&#xff0c;大部分开发的软件只需要用浏览器即可&#xf…

QT Mode/View之View

目录 概念 使用已存在的视图 使用模型 使用模型的多个视图 处理元素的选择 视图间共享选择 概念 在模型/视图架构中&#xff0c;视图从模型中获取数据项并将它们呈现给用户。数据的表示方式不必与模型提供的数据表示形式相似&#xff0c;而且可能与用于存储数据项的底层数…

【重学 MySQL】二十四、笛卡尔积的错误和正确的多表查询

【重学 MySQL】二十四、笛卡尔积的错误和正确的多表查询 笛卡尔积的理解和错误笛卡尔积的理解定义例子在数据库中的应用总结 笛卡尔积的错误 正确的多表查询使用 INNER JOIN使用 WHERE 子句&#xff08;隐式内连接&#xff09; 总结 在数据库查询中&#xff0c;特别是涉及到多表…

【python计算机视觉编程——9.图像分割】

python计算机视觉编程——9.图像分割 9.图像分割9.1 图割安装Graphviz下一步&#xff1a;正文9.1.1 从图像创建图9.1.2 用户交互式分割 9.2 利用聚类进行分割9.3 变分法 9.图像分割 9.1 图割 可以选择不装Graphviz&#xff0c;因为原本觉得是要用&#xff0c;后面发现好像用不…

大模型教程:使用 Milvus、vLLM 和 Llama 3.1 搭建 RAG 应用

vLLM 是一个简单易用的 LLM 推理服务库。加州大学伯克利分校于 2024 年 7 月将 vLLM 作为孵化项目正式捐赠给 LF AI & Data Foundation 基金会。欢迎 vLLM 加入 LF AI & Data 大家庭&#xff01;&#x1f389; 在主流的 AI 应用架构中&#xff0c;大语言模型&#xff…

数据清洗-缺失值处理-缺失值可视化图(竖线)

目录 一、安装所需的python包二、缺失值可视化分析2.1 可直接运行代码2.2 以某个缺失值数据进行可视化实战2.2.1 代码运行过程截屏&#xff1a;2.2.2 缺失图可视化&#xff1a; 感觉大家对原理性的东西不太感兴趣&#xff0c;那我就直接举例提供代码&#xff0c;以及详细的注释…

13、Python如何设置文件缓冲

什么是I/O操作&#xff0c;看一下百度百科的说法&#xff1a;I/O操作是指对设备与cpu连接的接口电路的操作&#xff0c;不是对外围设备直接进行操作。宏观上讲&#xff0c;I/O是信息处理系统&#xff08;例如计算机&#xff09;与外部世界&#xff08;可能是人或其他信息处理系…

Flutter之SystemChrome全局设置

一、简介 SystemChrome作为一个全局属性&#xff0c;很像 Android 的 Application&#xff0c;功能很强大。 二、使用详解 2.1 setPreferredOrientations 设置屏幕方向 在我们日常应用中可能会需要设置横竖屏或锁定单方向屏幕等不同要求&#xff0c;通过 setPreferredOrien…

阿里云镜像报错 [Errno 14] HTTP Error 302 - Found 问题解决记录

1、问题背景和解决思路 在本地安装 CentOS7 后&#xff0c;网络已调通可正常上网&#xff0c;但切换阿里云镜像后&#xff0c;使用 yum 安装软件时出现 “[Errno 14] HTTPS Error 302 - Found Trying other mirror.” 报错&#xff0c;原因是 yum 源配置问题。给出了详细的解决…

分布式可信认证:数据安全与隐私保护新范式

文章目录 前言一、可信数字身份成数据要素流通的关键二、分布式可信认证成数据安全与隐私保护新范式1、分布式可信认证很好地解决传统数字身份认证的痛点问题2、可信数字身份上升为国家战略三、安全是未来数字身份的基础1、有效的威胁建模策略是确保这些系统安全性的基石前言 …

数据清洗-缺失值填充-随机森林搜寻最优参数填充

目录 一、安装所需的python包二、采用随机森林算法进行缺失值填充2.1可直接运行代码2.2以某个缺失值数据进行实战代码运行过程截屏&#xff1a;填充后的数据截屏&#xff1a; 三、随机森林算法 (Random Forest) 介绍3.1随机森林的定义3.2随机森林的基本思想3.3随机森林的工作原…

语言模型中的多模态链式推理(论文复现)

语言模型中的多模态链式推理&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 文章目录 语言模型中的多模态链式推理&#xff08;论文复现&#xff09;简介摘要引言多模态思维链推理的挑战多模态CoT框架多模态CoT模型架构细节编码模块融合模块解码模…

redis短信登录模型

基于Session实现登录 &#xff0c;

Unity程序基础框架

概述 单例模式基类 没有继承 MonoBehaviour 继承了 MonoBehaviour 的两种单例模式的写法 缓存池模块 &#xff08;确实挺有用&#xff09; using System.Collections; using System.Collections.Generic; using UnityEngine;/// <summary> /// 缓存池模块 /// 知识点 //…

数据结构基础详解:哈希表【C语言代码实践篇】开放地址法__拉链法_哈希表的创建_增删查操作详解

文章目录 1.哈希表代码实现之开放地址法1.1 开放地址法创建哈希表1.2 开放地址法之查找1.3 开放地址法之插入1.4 开放地址法之删除 2.哈希表代码实现之链地址法(拉链法)2.1 链地址法之创建哈希表2.2 链地址法之查找2.3 链地址法之插入2.4 链地址法之删除 1.哈希表代码实现之开放…

Stable diffusion生图原理

简介 Stable diffusion 是一种基于扩散技术的深度学习模型&#xff0c;于2022年发布&#xff0c;是Stability AI公司推出的首要产品&#xff0c;它主要用于生成以文本描述为条件的详细图像&#xff0c;同时也可以进行补绘、外绘、重绘等任务&#xff0c;但原理都和文生图原理…

C++中矩阵的介绍及相关应用扩展详解

1. 矩阵概念 在数学中&#xff0c;矩阵&#xff08;Matrix&#xff09;是一个按照长方阵列排列的复数或实数集合&#xff0c;最早来自于方程组的系数及常数所构成的方阵。这一概念由19世纪英国数学家凯利首先提出。 矩阵是高等代数学中的常见工具&#xff0c;也常见于统计分析…

Qt-QPushButton按钮类控件(22)

目录 描述 使用 给按钮添加图片 给按钮添加快捷键 添加槽函数 添加快捷键 添加组合键 开启鼠标的连发功能 描述 经过上面的一些介绍&#xff0c;我们也尝试的使用过了这个控件&#xff0c;接下来我们就要详细介绍这些比较重要的控件了 使用 给按钮添加图片 我们创建…

线性表之单链表

在上一节我们学习了线性表中的顺序表&#xff0c;今天我们来学习一下线性表中的另一种结构——单链表 前言 我们在之前已经初步了解了数据结构中的两种逻辑结构&#xff0c;但线性结构中并非只有顺序表一种&#xff0c;它还有不少兄弟姐妹&#xff0c;今天我们再来学习一下单链…