java - spring中基于groups的动态POJO验证

标签 java spring validation spring-boot jackson

考虑以下 pojo 以供引用:

public class User{

    private  String username;
    private String firstName;
    private String middleName;
    private String lastName;
    private String phone;

    //getters and setters

}

我的应用程序基本上是基于 spring-boot 的 REST API,它公开了两个端点,一个用于创建用户,另一个用于检索用户。

“用户”属于某些类别,group-agroup-b 等,我从帖子请求的 header 中获得。

我需要在运行时验证用户数据,验证可能因用户组而异。

例如,属于 group-a 的用户可能将电话号码作为可选字段,而对于其他组可能是必填字段。

正则表达式也可能因组而异。

我需要能够配置 spring,以某种方式在创建 pojo 后立即动态验证我的 pojo,并根据它们的组触发它们各自的验证集。

也许我可以创建一个 yml/xml 配置来启用它?

我不想用 @NotNull@Pattern 注释我的 private String phone

我的配置如下:

public class NotNullValidator implements Validator {
    private String group;
    private Object target;

    public String getGroup() {
        return group;
    }

    public void setGroup(String group) {
        this.group = group;
    }

    public Object getTarget() {
        return target;
    }

    public void setTarget(Object target) {
        this.target = target;
    }

    @Override
    public void validate(Object o) {
        if (Objects.nonNull(o)) {
            throw new RuntimeException("Target is null");
        }
    }
}


public interface Validator {
    void validate(Object o);
}


@ConfigurationProperties(prefix = "not-null")
@Component
public class NotNullValidators {
    List<NotNullValidator> validators;

    public List<NotNullValidator> getValidators() {
        return validators;
    }

    public void setValidators(List<NotNullValidator> validators) {
        this.validators = validators;
    }
}


应用程序.yml

not-null:
  validators:

    -
      group: group-a
      target: user.username

    -
      group: group-b
      target: user.phone

我想配置我的应用程序以某种方式允许 validator 选择它们的目标(实际对象,不是 yml 中提到的字符串),并调用它们各自的 public void validate(对象 o) 在他们的目标上。

附言

请随时编辑问题以使其更好。

我正在使用 jackson 对 JSON 进行序列化和反序列化。

最佳答案

在我看来,解决问题的最简单方法不是使用 Spring 或 POJO 本身,而是使用设计模式。

您所描述的问题很容易通过策略模式解决方案解决。

您将策略与您期望在请求中使用的 header 匹配,该 header 描述了用户的类型,然后您在策略本身内部执行所述验证。

这将允许您对整个方法使用相同的 POJO,并根据每种用户的策略处理处理/解析和验证数据的细节。

这是来自 wiki 书籍的链接,其中包含该模式的详细说明

Strategy Pattern

假设您的策略有一个基本界面:

interface Strategy { 

    boolean validate(User user);
}

对于 2 种不同类型的用户,您有 2 种不同的实现:

public class StrategyA implements Strategy {

    public boolean validate(User user){

         return user.getUsername().isEmpty();
    }
}

public class StrategyB implements Strategy {

    public boolean validate(User user){

         return user.getPhone().isEmpty();
    }
}

您将策略属性添加到您的 User POJO 并分配 Strategy 的正确实现当您收到 post 请求时添加到该属性。

每次您需要验证该用户的数据时,您只需调用 validate分配策略的方法。

如果每个 User可以适合多种策略,您可以添加 List<Strategy>作为一个属性而不是单个属性。

如果您不想更改 POJO,则必须在每次收到 post 请求时检查哪种策略是正确的。

除了validate方法,您可以添加方法来处理数据,具体到每个策略。

希望这会有所帮助。

关于java - spring中基于groups的动态POJO验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46591861/

相关文章:

java - Spring 。验证期间错误 400

java - 创建闰年计划(包括世纪)

java - Hibernate 获取列属性

java.lang.NoSuchMethodException : JAXB Unmarshalling Interfaces

java - 可以在没有默认构造函数的情况下创建类吗?

java - 如何在 Hibernate Java obj 中添加 @XmlTransient

java - 如何向 XML DOM 对象添加命名空间前缀?

java - Spring Boot 微服务 Intellij Idea

javascript - 字段验证需要正则表达式帮助

使用 equalTo 的 jQuery 验证问题