Adi*_*lai 12 java validation spring jackson spring-boot
考虑以下pojo以供参考:
public class User{
private String username;
private String firstName;
private String middleName;
private String lastName;
private String phone;
//getters and setters
}
Run Code Online (Sandbox Code Playgroud)
我的应用程序基本上是基于spring-boot的REST API,它公开了两个端点,一个用于创建用户,另一个用于检索用户.
"用户"属于某些类别,group-a,group-b等,我从post请求的标题中获取.
我需要在运行时验证用户数据,验证可能会因用户组而有所不同.
例如,属于组-a的用户可能将电话号码作为可选字段,而对于某些其他组,它可能是必填字段.
正则表达式也可能因其组而异.
我需要能够配置spring,以某种方式动态验证我的pojo一旦创建它们各自的验证集就会根据它们的组触发.
也许我可以创建一个yml/xml配置,允许我启用它?
我宁愿不标注我private String phone有@NotNull和@Pattern.
我的配置如下:
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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
public interface Validator {
void validate(Object o);
}
Run Code Online (Sandbox Code Playgroud)
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
application.yml
not-null:
validators:
-
group: group-a
target: user.username
-
group: group-b
target: user.phone
Run Code Online (Sandbox Code Playgroud)
我想配置我的应用程序以某种方式允许验证器选择他们的目标(实际的对象,而不是 yml中提到的字符串),并public void validate(Object o)在他们的目标上调用他们各自的.
PS
请随时编辑问题以使其更好.
我正在使用jackson序列化和反序列化JSON.
ric*_*070 16
正如我所看到的,对您的问题最简单的解决方案不是Spring或POJO本身,而是设计模式.
您描述的问题很容易通过策略模式解决方案解决.
您将策略与您在请求中期望的标头匹配,描述用户的类型,然后在策略本身内执行所述验证.
这将允许您对整个方法使用相同的POJO,并根据每种类型的用户策略处理处理/解析和验证数据的细节.
这是来自维基书籍的链接,以及对模式的详细解释
假设您有一个基本的策略界面:
interface Strategy {
boolean validate(User user);
}
Run Code Online (Sandbox Code Playgroud)
对于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();
}
}
Run Code Online (Sandbox Code Playgroud)
您可以向UserPOJO 添加策略属性,并Strategy在收到发布请求时为该属性分配正确的实现.
每当您需要验证该用户的数据时,您只需调用validate指定策略的方法即可.
如果每个User策略都适合多种策略,则可以添加List<Strategy>属性而不是单个属性.
如果您不想更改POJO,则每次收到邮件请求时都必须检查哪个是正确的策略.
除了该validate方法,您还可以添加处理数据的方法,特定于每个策略.
希望这可以帮助.
您可以使用验证组来控制哪个类型的用户被验证哪个字段.例如:
@NotBlank(groups = {GroupB.class})
private String phone;
@NotBlank(groups = {GroupA.class, GroupB.class})
private String username;
Run Code Online (Sandbox Code Playgroud)
然后,您使用您提到的请求中的标头来决定要对哪个组进行验证.
有关完整示例,请参阅http://blog.codeleak.pl/2014/08/validation-groups-in-spring-mvc.html?m=1.
更新以包含更全面的示例:
public class Val {
private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
public boolean isValid(User user, String userType) {
usergroups userGroup = usergroups.valueOf(userType);
Set<ConstraintViolation<User>> constraintViolations = validator.validate(user, userGroup.getValidationClass());
return constraintViolations.isEmpty();
}
public interface GroupA {}
public interface GroupB {}
public enum usergroups {
a(GroupA.class),
b(GroupB.class);
private final Class clazz;
usergroups(Class clazz) {
this.clazz = clazz;
}
public Class getValidationClass() {
return clazz;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这不使用application.yaml,而是使用Spring内置的验证支持在注释中设置为每个组验证哪些字段的映射.
| 归档时间: |
|
| 查看次数: |
2662 次 |
| 最近记录: |