Hibernate Validator With Validation groups for Serialization With Write Access

Hibernate Validator With Validation groups for Serialisation With Write Access

我有一个端点,用户可以在其中注册 email/password。但是我想检查密码是否不为空,但我也只想反序列化密码,因为我不想将它发送回客户端。

public class User {
  @NotEmpty
  private String email;
  @JsonProperty(access = Access.WRITE_ONLY)
  @NotEmpty
  private String password;

  // Getters and setters
  ...
}

端点

@Path("/register")
@POST
public Response register(@Valid User user) {
  ...
}

而不是 Access.WRITE_ONLY 我还尝试了 getter 上的 @JsonIgnore 和 setter 上的 @JsonProperty

问题是 Hibernate Validator 一直抱怨密码为空,即使我 POST 用户设置了密码:

"{"errors":["password may not be empty"]}"

我该如何解决这个问题?还是我必须在端点中实现自己的 NotEmpty 验证逻辑?

这可以使用验证组来完成。以下是实现此目标的方法:

public class GroupValidationTest {


    public static void main(String[] args) {
        Validator v = Validators.newValidator();


        Model m = new Model();
        m.user = "Harry";
        m.password = "Potter";

        Set<ConstraintViolation<Model>> validate = v.validate(m, INPUT.class);
        System.out.println(validate.size());

        validate = v.validate(m, INPUT.class, OUTPUT.class);
        System.out.println(validate.size());

        validate = v.validate(m, OUTPUT.class);
        System.out.println(validate.size());

        m.password = null;

        validate = v.validate(m, INPUT.class, OUTPUT.class);
        System.out.println(validate.size());

        validate = v.validate(m, OUTPUT.class);
        System.out.println(validate.size());
    }

    public static class Model {

        @NotEmpty(groups={INPUT.class, OUTPUT.class})
        public String user;

        @NotEmpty(groups={INPUT.class})
        public String password;

    }

    public interface INPUT {}
    public interface OUTPUT {}

}

这输出:

0 -> Full object, validate INPUT 
0 -> Full object, validate INPUT + OUTPUT
0 -> Full object, validate OUTPUT
1 -> null password, validate INPUT + OUTPUT
0 -> null password, validate OUTPUT

解释:

Hibernate 验证器框架支持验证约束组。它们用于告诉验证器在特定验证尝试中要验证哪些组。您可以在这里阅读所有相关信息:

https://docs.jboss.org/hibernate/validator/4.2/reference/en-US/html/validator-usingvalidator.html#example-group-interfaces

我在代码示例中所做的是:

  • 定义 2 个组 INPUTOUTPUT
  • 将用户属性标记为要针对两个组进行验证
  • 将密码 属性 标记为仅在输入时验证

对于 REST 方面(不同的问题),输入和输出的验证通常由拦截器完成,通常是 MessageBodyReader 和 Writer class。这些负责读取用户输入并将其写出。您可以在球衣文档页面上阅读相关内容。

然后您可以实现自己的验证 reader/writer,知道在读取用户输入时只验证 INPUT,而在写回序列化正文时只验证 OUTPUT

希望对您有所帮助,

阿图尔