SpringBoot利用ConstraintValidator实现自定义注解校验

news2024/12/28 20:50:19

一、前言

        ConstraintValidator是Java Bean Validation(JSR-303)规范中的一个接口,用于实现自定义校验注解的校验逻辑。ConstraintValidator定义了两个泛型参数,分别是注解类型和被校验的值类型。在实现ConstraintValidator接口时,需要重写initialize、isValid等方法,并实现具体的校验逻辑。

二、自定义注解校验参数是否为Null

        比如校验参数name不能为null或者空字符串,先编写@interface类ValidNull:

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {NullValidator.class})
public @interface ValidNull {
    // 默认错误消息
    String message() default "name不能为空";

    // 分组
    Class<?>[] groups() default {};

    // 负载
    Class<? extends Payload>[] payload() default {};
}

        再编写校验类 NullValidator:

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class NullValidator implements ConstraintValidator<ValidNull, String> {
    @Override
    public void initialize(ValidNull constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (null == value || "".equals(value)){
            return false;
        }
        return true;
    }
}

        编写实体类NullTest,并在此加上注解:

import lombok.Data;

@Data
public class NullTest {

    @ValidNull
    private String name;
}

         最后在controller层进行调用校验,注意需要在实体类前面加上@Validated 注解,否则校验是不生效的:

    @PostMapping(value = "/test")
    public RetResult test(@RequestBody @Validated NullTest nullTest) {
        System.err.println(nullTest.getName());
        return RetResult.success();
    }

        测试结果:

        当name有值时,正常通过:

         当name为null时,提示校验错误信息:

        当name为空字符串时, 提示校验错误信息:

 

三、自定义注解校验参数值大小

        比如一个参数是数字,需要校验其大小,方法如下:

        先编写@interface类:

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {NumValidator.class})
public @interface ValidNum {
    int value();

    // 默认错误消息
    String message() default "num不能大于20";

    // 分组
    Class<?>[] groups() default {};

    // 负载
    Class<? extends Payload>[] payload() default {};
}

        这里有添加value,这个可以在使用该注解时,传参数,下面的默认错误信息,也可以在使用注解时一起使用,只是在没有传参数时默认使用而已。

        编写NumValidator校验类:

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class NumValidator implements ConstraintValidator<ValidNum,Integer> {
    private Integer value;

    @Override
    public void initialize(ValidNum constraintAnnotation) {
        this.value = constraintAnnotation.value();
    }

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        if(value > this.value){
            return false;
        }
        return true;
    }
}

        可以看到这里也定义了value,在initialize里面初始化,也就是获取使用该注解的地方传入的值。

        编写实体类NullTest:

import lombok.Data;

@Data
public class NumTest {

    @ValidNum(value = 30, message = "数值不能大于30")
    private Integer num;
}

        在controller层测试:

    @PostMapping(value = "/test")
    public RetResult test(@RequestBody @Validated NumTest numTest) {
        System.err.println(numTest.getNum());
        return RetResult.success();
    }

        测试结果:

        当传入参数小于30时:

        当传入参数大于30时:

 

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

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

相关文章

【业务功能篇77】微服务-OSS对象存储-上传下载图片

3. 图片管理 文件存储的几种方式 单体架构可以直接把图片存储在服务器中 但是在分布式环境下面直接存储在WEB服务器中的方式就不可取了&#xff0c;这时我们需要搭建独立的文件存储服务器。 3.1 开通阿里云服务 针对本系统中的相关的文件&#xff0c;图片&#xff0c;文本等…

JavaSE 数组

定义&#xff1a; int []arr; int arr[]; 初始化 // 完整格式 int arr[] new int[]{1, 2, 3}; // 简单格式 int arr[] {1, 2, 3}; 数组的元素访问、遍历 按照下标访问即可。数组的长度函数为 arr.length()。idea快速生成遍历的方法&#xff1a;数组名.fori 静态初始化 &a…

9.Sentinel哨兵

1.Sentinel Sentinel&#xff08;哨兵&#xff09;是由阿里开源的一款流量控制和熔断降级框架&#xff0c;用于保护分布式系统中的应用免受流量涌入、超载和故障的影响。它可以作为微服务架构中的一部分&#xff0c;用于保护服务不被异常流量冲垮&#xff0c;从而提高系统的稳定…

【神州数码】BGP路由器案例

SwitchB、SwitchC和SwitchD位于AS200中&#xff0c;SwitchA位于AS100中。SwitchA和SwitchB共享一个相同的网络段11.0.0.0。而SwitchB和SwitchD彼此物理上不相邻。 则SwitchA的配置如下&#xff1a; SwitchA(config)#router bgp 100SwitchA(config-router-bgp)#neighbor 11.1.1…

指针(初阶)

1. 指针是什么&#xff1f; 指针是什么&#xff1f; 指针理解的2个要点&#xff1a; 1. 指针是内存中一个最小单元的编号&#xff0c;也就是地址 2. 平时口语中说的指针&#xff0c;通常指的是指针变量&#xff0c;是用来存放内存地址的变量 总结&#xff1a;指针就是地址&…

Wlan——锐捷零漫游网络解决方案以及相关配置

目录 零漫游介绍 一代零漫游 二代单频率零漫游 二代双频率零漫游 锐捷零漫游方案总结 锐捷零漫游方案的配置 配置无线信号的信道 开启关闭5G零漫游 查看配置 零漫游介绍 普通的漫游和零漫游的区别 普通漫游 漫游是由一个AP到另一个AP或者一个射频卡到另一个射频卡的漫…

jquery实现单独使用laydate时间控件设置开始时间,结束时间最大最小值以及设置默认时分秒

因项目内 会话时间所用框架为layui 里面的laydate时间控件 具体的设置文档里面都有些 我所用的这个不是日期时间范围 而是单独的日期时间的控件 意思就是两个是单独的 但是需要设置的是 开始最大 时间为结束时间的最小值 结束最小时间为开始结束的最大值 其余不能点击 当我选择…

leetcode54. 螺旋矩阵(java)

螺旋矩阵 题目描述解题 收缩法 上期经典算法 题目描述 难度 - 中等 原题链接 - leecode 54 螺旋矩阵 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7…

潮湿对电子元器件有哪些影响?如何选择电子防潮柜?

随着科技的飞速发展&#xff0c;电子设备的应用越来越广泛&#xff0c;无论是生活、工业、农业领域随处可见各种各样的电子设备。电子设备在稳定的环境中是可以短时间存放的&#xff0c;但如果放置环境的湿度和温度发生较大改变&#xff0c;其性能会受到影响。电子设备受潮会有…

开学后运营校园跑腿小程序行不行?

校园跑腿小程序的运营是完全可行的&#xff0c;它为学生提供了便捷的校园代办服务。随着社会的发展和生活节奏的加快&#xff0c;越来越多的学生需要在学业之余处理个人事务&#xff0c;如购买日常用品、快递代取、打印复印文件等。传统的校园跑腿服务通常由个别学生或者组织提…

LeetCode3.无重复字符的最长子串

虽然是一道中等题&#xff0c;但我5分钟就写完了&#xff0c;而且是看完题就知道怎么写&#xff0c;这一看就知道双指针&#xff0c;一个左一个右&#xff0c;右指针往后移如果没有重复的长度1&#xff1b;如果有重复的&#xff0c;左指针往右移&#xff0c;那如何判断重复呢&a…

MyBatis相关知识

什么是MyBatis&#xff1f; MyBatis 是一个开源、轻量级的数据持久化框架&#xff0c;是 JDBC 和 Hibernate 的替代方案。MyBatis 内部封装了 JDBC&#xff0c;简化了加载驱动、创建连接、创建 statement 等繁杂的过程&#xff0c;开发者只需要关注 SQL 语句本身。 什么是持久…

SpringBoot案例-修改员工-查询回显

根据页面原型&#xff0c;明确需求 页面原型 需求 在员工信息栏的右侧存在一个编辑按钮&#xff0c;点击该按钮可以对员工信息进行修改&#xff0c;但是修改之前&#xff0c;会出现上述页面&#xff0c;将员工原有的信息进行展示回显。 阅读接口文档 接口文档的链接如下&am…

API接口文档利器:Swagger 和 接口调试利器:Postman

2.接口相关工具 2.1API接口文档利器&#xff1a;Swagger 2.1.1Swagger介绍 Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务 (https://swagger.io/)。 它的主要作用是&#xff1a; 使得前后端分离开发更加方便&#xff0…

把握医学营养趋势 健启星加速突围

随着“健康中国”战略的提出&#xff0c;大健康产业上升到国家战略高度&#xff0c;进入高速发展期。市场数据显示&#xff0c;医学营养市场发展势头迅猛&#xff0c;年平均增速超过30%&#xff0c;中国医学营养市场也迎来高速发展。但目前品牌处于高度分散的状态&#xff0c;市…

【音视频】奇怪问题记录-执法仪引起的问题

现象 打开&#xff0c;关闭&#xff0c;再打开&#xff0c;反复这样操作&#xff0c;几次后&#xff0c;可能 出现&#xff08;1&#xff09;拉不出来&#xff08;2&#xff09;绿色的屏 &#xff08;3&#xff09;黑色的屏&#xff08;如上&#xff09;。 &#xff08;4&am…

使用Token方式实现用户身份鉴权认证

一、什么是Token&#xff1f; Token&#xff0c;也称为“令牌”&#xff0c;是服务端生成的一串字符串&#xff0c;以作客户端进行请求的一个令牌&#xff0c;当第一次登录后&#xff0c;服务器生成一个Token便将此Token返回给客户端&#xff0c;以后客户端只需带上这个Token前…

基于风驱动算法优化的BP神经网络(预测应用) - 附代码

基于风驱动算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于风驱动算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.风驱动优化BP神经网络2.1 BP神经网络参数设置2.2 风驱动算法应用 4.测试结果&#xff1a;5.Matlab代…

关于BigDecimal你不知道的那些事儿

&#x1f388;个人主页:&#x1f388; :✨✨✨ 阳光宅猿的博客站✨ &#x1f35f;&#xff08;正在建设当中&#xff0c;感兴趣的伙伴加v: sunsuncoder 一起交流&#xff09;&#x1f35f; &#x1f511;个人信条:&#x1f511; 大道至简 知行合一&#x1f335; &#x1f349;本…

Four Operations

一、题目 Little Ruins is a studious boy, recently he learned the four operations! Now he want to use four operations to generate a number, he takes a string which only contains digits ‘1’ - ‘9’, and split it into 5 5 intervals and add the four operat…