【问题标题】:Validate when fields depend on one another验证字段何时相互依赖
【发布时间】:2020-04-17 04:36:35
【问题描述】:

我将请求对象名称 Person 传递给控制器​​。假设该对象有 2 个两个字段。以下业务规则适用:

  • 如果字段age 的值sin 应留空;
  • 如果不是,则会产生异常消息the sin should be blank with age < 18,或者另一种方法是将字段sin设置为空字符串("")。

当这些输入相互依赖时,我验证这些输入的最佳方式是什么。我处理它们的方法是在控制器方法中验证它们。所以它应该看起来像这样

@GetMapping("/..."
public ResponseEntity<PersonResponse> getPersonResult(GetPersonRequest request)
{
    if (request.getAge() < 18)
    {
        if (request.getSin.length > 0)
            request.setSin("") 
    }
    PersonResponse response = callThirdPartyAPIToRetrieveInformationAboutThatPerson(request)
    return response ;
}

还有更优雅的编码方式吗?控制器方法可以包含任何类似的验证逻辑吗?我是否违反了 SOLID 设计中的单一责任?

【问题讨论】:

  • 你一次问了太多问题..

标签: spring validation spring-mvc design-patterns spring-annotations


【解决方案1】:

是的,当然!这是一个很好的方法:类的单一职责 - 控制器负责处理数据,验证器 - 用于验证数据;开闭原则——经过验证的数据是不能通过控制器的方法改变的; Liskov 原则与基本 OOP 原则相关 - 验证器是独立的实体,无需任何额外操作即可更改为另一个;接口隔离清晰,没有任何描述(完全分离的类);依赖倒置也是可以理解的——使用注解接口,控制器对其实现一无所知。所以,从意识形态和语言语法来看,这是一个非常好的方法。

实施。

  1. 创建类级别@interface。所有字段均可访问。
  2. 使用验证逻辑创建 ConstraintValidator 类。
  3. 在控制器方法中为@RequestBody 设置此注解。
  4. 为控制器添加验证功能:@Validated 用于控制器类,@Valid 用于控制器方法中的@RequestBody 实体。

如果需要处理验证异常,只需抛出一个新异常并在@ControllerAdvise类中处理,验证或控制器类中无需处理代码。

the official resource 中创建类级验证器的示例。

【讨论】:

  • 我考虑过为此创建自定义注释。但是,当字段相互依赖以获得验证结果时,我该怎么做呢?能给我一些代码供参考吗?
  • 我添加了链接docs.jboss.org/hibernate/stable/validator/reference/en-US/… ...看看这个。创建新的注解并在类中实现 ConstraintViolation 您使用一个对象,它的所有字段都可用,您可以处理它们及其依赖关系。
猜你喜欢
  • 2016-01-10
  • 1970-01-01
  • 2021-10-13
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-27
相关资源
最近更新 更多