为PUT请求绕过唯一性验证器

时间:2018-10-17 09:09:53

标签: java spring hibernate spring-mvc spring-validator

我面临一个问题,就是无法绕过一个用于在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请求且字段“名称”未更改时,都会出现此问题-验证程序检查唯一性,并且因为它已经在数据库中具有给定名称的条目而无法通过。

另一方面,我要指出的是,由于无法解释的原因,无法将约束应用于数据库中的表。

是否有一个聪明的解决方案而不必使代码过于混乱?我希望有一种方法可以让验证器知道,无论何时PUT进入时都遵循与POST请求不同的逻辑。

1 个答案:

答案 0 :(得分:0)

我可以假设您的验证器已经是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