谷粒商城 - 编写一个自定义校验注解

news2024/11/20 20:28:07

目录

开始

未来实现效果

第一步:编写自定义校验注解

第二步:编写自定义校验器

第三步:编写配置文件

效果演示


 

开始


未来实现效果

编写一个 @ListValue 注解,可以实现功能有:

  • 限定字段的值,例如指定只能为 1 或 2.
  • 支持自定义错误信息.
  • 支持分组校验.

第一步:编写自定义校验注解

import jakarta.validation.Constraint
import jakarta.validation.Payload
import kotlin.annotation.AnnotationRetention.RUNTIME
import kotlin.annotation.AnnotationTarget.*
import kotlin.reflect.KClass

@MustBeDocumented
@Constraint(validatedBy = [ListValueConstraintValidator::class])
@Target(FUNCTION, FIELD, ANNOTATION_CLASS, CONSTRUCTOR, VALUE_PARAMETER, TYPE)
@Retention(RUNTIME)
annotation class ListValue(
    val message: String = "{org.cyk.gulimall.product.infra.config.exception.ListValue.message}",
    val groups: Array<KClass<*>> = [],
    val payload: Array<KClass<out Payload>> = [],

    val vals: IntArray = []
)

a)注解解释: 

  • @MustBeDocumented

    这个注解表示使用该注解的注解应该包含在生成的Kotlin文档中。换句话说,当使用KDoc生成文档时,应用了 MustBeDocumented 的注解将会出现在文档中。

  • @Constraint(validatedBy = [ListValueConstraintValidator::class])

    这个注解定义了该注解是一个校验约束,并且指定了用来校验该注解的逻辑类。ListValueConstraintValidator::class 是一个自定义校验类(下文中详细讲)

  • @Target

    这个注解定义了自定义注解可以应用的目标元素。可以是方法、字段、注解类型、构造函数、参数或类型使用。在Kotlin中,它们分别对应 FUNCTION, FIELD, ANNOTATION_CLASS, CONSTRUCTOR, VALUE_PARAMETER, TYPE 这样可以控制自定义注解可以应用于哪些代码元素。

  • @Retention(RUNTIME)

    这个注解定义了自定义注解的保留策略.  RUNTIME表示注解将在运行时保留,因此可以通过反射机制访问注解信息。其他可选的保留策略包括 SOURCE(只在源代码中保留)和 CLASS(在编译时保留,但在运行时不可见)。

b)成员解释:

Note:message、groups、payload 在自定义校验注解中必须要有,因为是 JSR303 中的规范(可以参考其他校验注解,例如 @NotBlank)

  • message:自定义错误信息去哪个地方取(下文中会详细讲解).
  • groups:支持分组校验功能.
  • payload:支持自定义负载信息.
  • vals:vals 是自定义的,用来给校验注解传递值,例如 @ListValue(vals = [1, 2]).

第二步:编写自定义校验器

上面提到的 @Constraint(validatedBy = [ListValueConstraintValidator::class]) 中的 ListValueConstraintValidator 就是自定义校验器,负责处理校验核心逻辑.

例如你是这样使用注解的@ListValue(vals=[1,2]) 

那么 initialize 方法就可以拿到其中 vals,进行初始化(逻辑自定义)

isValid 方法就是将来使用时触发的逻辑

import jakarta.validation.ConstraintValidator
import jakarta.validation.ConstraintValidatorContext

class ListValueConstraintValidator: ConstraintValidator<ListValue, Int> {

    private lateinit var set: Set<Int>

    /**
     * 初始化方法
     */
    override fun initialize(constraintAnnotation: ListValue) {
        set = constraintAnnotation.vals.toSet()
    }

    /**
     * @param p0: 需要校验的值
     */
    override fun isValid(p0: Int, p1: ConstraintValidatorContext): Boolean {
        return set.contains(p0)
    }

}

Ps:@Constraint(validatedBy = [ ... ]) 中还可以指定多个不同的校验器,来适配不同类型的校验

第三步:编写配置文件

在编写自定义校验注解时,里面有一个成员 message,他就会去配置文件(ValidationMessages.properties)找这个配置.

因此这里我们在 resource 目录下需要创建一个 ValidationMessages.properties 配置文件,编写内容如下:

org.cyk.gulimall.product.infra.config.exception.ListValue.message=must be a specified value~

Ps:key 就是 message 默认值(一般就取 自定义校验注解的全限定类名.message ),value 就是校验错误提示的默认信息

效果演示

a)demo 如下:

    @GetMapping("/value")
    fun getValue(
        @RequestBody @Valid dto: ValueDto
    ): ApiResp<String> {
        return ApiResp.ok("ok")
    }


data class ValueDto (
    @field:ListValue(vals = [1, 2])
    val status: Int
)

a)当输入错误的值时.

Ps:这个默认错误信息,也可以在统一异常处理中,专门提取出来.

b)输入的值正确时

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

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

相关文章

注解复习(java)

文章目录 注解内置注解**Deprecated**OverrideSuppressWarnings【不建议使用】Funcationallnterface 自定义注解元注解RetentionTargetDocumentedInherited 和 Repeatable 反射注解 前言&#xff1a;笔记基于动力节点 注解 注解可以标注在 类上&#xff0c;属性上&#xff0c…

LabVIEW中使用 DAQmx Connect Terminals作用意义

该图展示了如何在LabVIEW中使用 DAQmx Connect Terminals.vi 将一个信号从一个源端口连接到一个目标端口。这种处理有以下几个主要目的和作用&#xff1a; 同步操作&#xff1a; 在多任务、多通道或多设备系统中&#xff0c;可能需要不同的组件在同一时刻执行某些操作。通过将触…

深入理解循环神经网络(RNN)

深入理解循环神经网络&#xff08;RNN&#xff09; 循环神经网络&#xff08;Recurrent Neural Network, RNN&#xff09;是一类专门处理序列数据的神经网络&#xff0c;广泛应用于自然语言处理、时间序列预测、语音识别等领域。本文将详细解释RNN的基本结构、工作原理以及其优…

【鸿蒙学习笔记】创建自定义组件

官方文档&#xff1a;创建自定义组件 目录标题 [Q&A] 如何自定义组件&#xff1f;&#xff11;・struct 自定义组件名 {...}&#xff12;・build()函数&#xff1a;&#xff13;・&#xff20;Component&#xff14;・Entry&#xff15;・Reusable 自定义组件的参数 buil…

一篇经典Python编程常用的30个操作以及代码演示

这些案例将涵盖数据处理、算法、文件操作、数据可视化、网络编程、机器学习等多个领域. 以下是具体的操作步骤和示例代码&#xff1a; 基础操作 1. 计算两个数的和 def add(a, b): return a b print(add(3, 5)) 2. 判断一个数是否为偶数 def is_even(n): return n % …

谷歌+火狐浏览器——实现生成二维码并实现拖动——js技能提升

最新遇到的问题&#xff1a;前两个二维码拖动不了&#xff0c;只有第三个一维码生成后&#xff0c;才可以拖拽 【问题】&#xff1a;出现在都是绝对定位&#xff0c;但是没有指定z-index导致的。 解决办法&#xff1a;在方法中添加一个变量 renderDrag(id) {var isDragging f…

RDNet实战:使用RDNet实现图像分类任务(一)

论文提出的模型主要基于对传统DenseNet架构的改进和复兴&#xff0c;通过一系列创新设计&#xff0c;旨在提升模型性能并优化其计算效率&#xff0c;提出了RDNet模型。该模型的主要特点和改进点&#xff1a; 1. 强调并优化连接操作&#xff08;Concatenation&#xff09; 论文…

Java反射与Fastjson的危险反序列化

什么是Java反射&#xff1f; 在前文中&#xff0c;我们有一行代码 Computer macBookPro JSON.parseObject(preReceive,Computer.class); 这行代码是什么意思呢&#xff1f;看起来好像就是我们声明了一个名为 macBookPro 的 Computer 类&#xff0c;它由 fastjson 的 parseObje…

【解决ERROR】usage:conda [-h][-V] command... conda:error:unrecognized arguments

解决方法 conda env create --file conda3_520_env_deepPath.yml

拖地机检测液位的原理-管道液位传感器

在现代洗地机中&#xff0c;确保水箱液位充足是保证清洁效率和质量的关键之一。为了实现这一功能&#xff0c;洗地机通常配备了管道光电液位传感器&#xff0c;这种传感器利用先进的光学感应原理来准确检测水箱中的液位情况。 管道光电液位传感器的工作原理基于光学传感技术&a…

新手教学系列——crontab 使用不当引发的服务器性能问题

起因及症状 最近,我们的一台服务器随着运行时间的增加,逐渐出现了压力过大的问题。具体表现为数据库连接数飙升至 4000+,Redis 频繁超时,系统报错文件打开数过多等。针对这些问题,我们逐一检查了数据库连接池、Redis 连接池以及系统的 ulimit 配置,但都未能找到问题的根…

k8s中port,targetPort,nodePort,containerPort的区别

一、说明 在 Kubernetes 中&#xff0c;port、targetPort、nodePort 和 containerPort 是用于定义服务&#xff08;Service&#xff09;和容器之间网络通信的不同参数。 它们各自的作用和含义如下&#xff1a; 1. port 定义&#xff1a;这是服务对外暴露的端口号。作用&#x…

eBPF实战教程五|如何使用USDT探针定位MySQL异常访问(含源码)

前言 各位小伙伴们&#xff0c;非常感谢你们对我们eBPF专题系列文章的持续关注和热情支持&#xff01;在之前的文章中&#xff0c;我们深入探讨了如何手写一个uprobe探测用户态程序。许多热心的小伙伴给我们发私信表达了他们对eBPF技术在数据库领域应用的浓厚兴趣&#xff0c;…

2024建博会|博联AI大模型全屋智能引领智能体验新纪元

7月8日&#xff0c;2024中国建博会&#xff08;广州&#xff09;在广交会展馆及保利世贸博览馆盛大启幕。BroadLink博联智能携AI大模型全屋智能以及AI商业照明解决方案惊喜亮相&#xff0c;全方位展示AI大模型在智能家居领域的前沿应用成果。 本次建博会&#xff0c;博联智能带…

《大语言模型的临床和外科应用:系统综述》

这篇题为《大语言模型的临床和外科应用&#xff1a;系统综述》的文章对大语言模型&#xff08;LLM&#xff09;目前在临床和外科环境中的应用情况进行了全面评估。 大语言模型&#xff08;LLM&#xff09;是一种先进的人工智能系统&#xff0c;可以理解和生成类似人类的文本。…

如何在不关闭防火墙的情况下,让两台设备ping通

问题现象 如题&#xff0c;做虚拟机实验的时候&#xff0c;有一台linux系统的虚拟机配置的ip地址是192.168.172.181 物理主机的ip地址是192.168.172.1 此时物理主机可以ping通虚拟机 但是虚拟机不能ping通物理主机 此时我们可以想到&#xff0c;有可能是物理主机防火墙的原因。…

S32V234平台开发(一)快速使用

快速使用 准备供电复位选择串口通信启动选择显示登陆系统 准备供电 s32v234可以使用两种电源供电 一种是左边电源端子&#xff0c;一种是右边电源适配器(12V 3A) 注意:不要同时使用两种电源同时供电 复位选择 Pressing POR RESET pulls active low EXT_POR signal on S32V2…

基于蓝牙iBeacon定位技术的商场3D楼层导视软件功能详解与实施效益

在现代商场的繁华与复杂中&#xff0c;寻找目的地往往令人头疼。维小帮3D楼层导视软件以其创新技术&#xff0c;为顾客带来无缝、直观的跨楼层导航体验&#xff0c;让每一次商场消费都成为享受。 商场3D楼层导视软件功能服务 3D多楼层导视地图&#xff0c;商场布局一览无遗 …

卷技术还是卷应用?李彦宏给出了明确答案

如何理解李彦宏说的“不要卷模型&#xff0c;要卷应用” 引言 7月4日&#xff0c;2024世界人工智能大会在上海世博中心召开。百度创始人兼CEO李彦宏在产业发展主论坛上呼吁&#xff1a;“大家不要卷模型&#xff0c;要卷应用&#xff01;”这句话引起了广泛讨论。李彦宏认为&a…

安装nodejs | npm报错

nodejs安装步骤: 官网&#xff1a;https://nodejs.org/en/ 在官网下载nodejs: 双击下载下来的msi安装包&#xff0c;一直点next&#xff0c;我选的安装目录是默认的: 测试是否安装成功&#xff1a; 输入cmd打开命令提示符&#xff0c;输入node -v可以看到版本&#xff0c;说…