java - 绕过 PUT 请求的唯一性验证器
问题描述
我面临一个问题,即无法绕过用于在 POST 和 PUT 请求时检查对象名称的唯一性的单个验证器。详情如下:
鉴于,
具有两个字段的类 UserDTO
private int id
@UserUniquenessValidator
private String name
控制器方法签名
post(@Valid @RequestBody UserDTO userDTO)
put(@PathVariable int id, @Valid @RequestBody UserDTO userDTO)
应用于字段名称的自定义验证器
@UserUniquenessValidator
现在,每当我尝试发布新用户时,自定义验证器只需将名称字段与数据库中的其他记录进行比较,如果没有找到任何记录,则返回 true,反之亦然。
每次发送未更改字段“名称”的 PUT 请求时都会出现问题 - 验证器检查唯一性并且不会通过,因为它已经在 DB 中有一个具有给定名称的条目。
在旁注中,我应该提到约束不能应用于数据库中的表,原因太长而无法解释。
是否有一个聪明的解决方案来解决这个问题而不必过多地混乱代码?我希望有一种方法可以让验证者知道,任何时候 PUT 都会遵循与 POST 请求不同的逻辑。
解决方案
我可以假设您的验证器已经是一个 Spring bean:您检索数据库记录以追求名称的唯一性。
假设验证器只涉及请求验证上下文,你可以注入一个HttpServletRequest
代理给验证器一个请求上下文
@Autowired
private HttpServletRequest request;
您可以从中找出当前的 HTTP 方法。
@Override
public boolean isValid(String name, ConstraintValidatorContext context) {
return HttpMethod.PUT.name().equals(request.getMethod()) ||
validate(name, context);
}
private boolean validate(String name, ConstraintValidatorContext context) {
// validate name uniqueness
return false;
}
为了避免硬编码HttpMethod.PUT.name()
,注释可以定义String[] excludeFor
:
@UserUniquenessValidator(excludeFor={"PUT"})
我发现注释名称不正确。UserUniquenessValidator
对于处理此注解但不适用于注解本身的类来说,这是一个很好的标题。我会命名它@UniqueName
。
推荐阅读
- apache-spark - 独立和集群模式下的分区数
- react-native - 在 React Native 中搜索响应数据的最佳方式?
- swift - swift ui 导航栏后退按钮仅被隐藏它正在占用空间和多个后退按钮占用空间询问我导航到其他页面
- javascript - 如果页面上存在链接,则在单击时添加类,javascript
- php - 用php从csv快速更新大量数据mysql
- package - HOMEBREW - 在没有 github 的情况下在本地创建一个包
- java - DataStream Flink中从JDBC源读取数据的问题
- html - 在 Angular 中将条件渲染逻辑放在哪里?
- javascript - 如何将数字数组字符串转换为数字数组?(JS)
- powershell - HTML 表格转 CSV