java - 如何在 Spring 的一个 ConstraintValidator 中同时验证 @PathVariable 和 @RequestBody?
问题描述
我在控制器中有一个端点处理程序方法:
@PutMapping("/users/{userId}")
public UserDto updateUser(@PathVariable UUID userId, @RequestBody UserRequestDto updateRequest) {
...
}
在UserRequestDto
对象内部,我有一个email
字段。
我想验证该email
值是否尚未使用。
创建不是问题,因为我只需要检查电子邮件是否不在数据库中。我创建了一个简单的 ConstraintValidator 并且一切正常。
但是对于更新,我需要检查更新的电子邮件地址是否未被其他人使用并省略当前更新的用户。所以我需要同时对两者进行userId
操作updateRequest
。创建自定义 ConstraintValidator 来处理这种情况是否可行?
解决方案
由于您从 a 发布了代码@RestController
,我假设我们正在讨论控制器级别的验证。我可以分享一些观察:
1)请注意,您正在尝试将与业务逻辑相关的验证放入ConstraintValidator
. 在您的情况下,它正在验证来自保存请求属性的数据传输对象(即)的字段。UserRequestDto
在控制器级别,我们应该只验证请求本身(即“是否提供了所有必要的信息,以便我可以实际开始执行操作?”)。
2)因为对“有效”的理解很可能因业务用例而异,业务逻辑相关的验证应该进入一个@Service
可以执行特定于用例的验证的 bean(例如“是否有任何其他用户具有相同的用户名或电子邮件?”)。大多数情况下,这是通过手动检查不同的条件来完成的,例如执行数据库查询或咨询其他应用程序。在这个级别上ConstraintValidator
,s 会适得其反。
3) ConstraintValidator
s 大部分时间用于执行语法验证(即“所有必要的值都以预期的格式存在吗?”)但用于语义验证的时间不多(即“根据我的业务逻辑,信息是否正确(这可能涉及数据库查询和咨询其他应用程序)?”)。
因此,在您的情况下,如果您需要检查客户端是否以特定格式传递了所有必需的属性,则使用自定义验证您的UserRequestDto
对象 绝对没问题。ConstraintValidator
但是,检查用户名/电子邮件是否已被另一个用户使用应该由逻辑层以特定于用例的方式执行 - 在ConstraintValidator
.
推荐阅读
- r - 如何在一个绘图中加入来自不同数据集的绘图层 - ggplot2?
- django - utf-8' 编解码器无法解码位置 112483 中的字节 0xa9:django 中的起始字节无效?
- excel - 如何将字符串="1xxxx, 11xxxx, 21xxxx" 提取到数组中[{objecta:1xxxx,objectb:11xxxx,objectc:21xxxx}]
- sumo - 运行“python示例/SUMO/highway.py”时出现FLOW错误
- flutter - 文本输入值正在消失 Flutter
- ubuntu - ffprobe 在 Ubuntu 上抛出 SegFault 而不是 Windows
- html - 输出中的字体不会改变
- php - PHP 数组整数
- javascript - 如何读取 js-year-calendar 库(无法读取 null 的属性“classList”)
- python-3.x - 带有 Apache2 的 Python3 脚本无法完全正常工作