带有写入访问序列化的验证组的Hibernate验证器

时间:2016-10-18 10:23:42

标签: java jersey jackson hibernate-validator

我有一个端点,用户可以使用她的电子邮件/密码进行注册。但是,我想检查密码是不是空的,但我也想只反序列化密码,因为我不想把它发回给客户端。

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,在设置器上尝试了@JsonProperty

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

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

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

1 个答案:

答案 0 :(得分:1)

这可以使用验证组完成。以下是您将如何实现这一目标:

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

Explenation:

Hibernate验证器框架支持验证约束的组。它们用于告知验证者哪些组在特定的验证尝试中进行验证。你可以在这里阅读所有相关内容:

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

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

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

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

然后,您可以实现自己的验证读取器/写入器,该读取器/写入器在读取用户输入时仅知道INPUT,而仅在编写序列化主体时验证OUTPUT

我希望有所帮助,

artur