验证字段何时相互依赖

时间:2019-12-27 06:23:17

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

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

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

当这些输入彼此依赖时,验证它们的最佳方法是什么?我处理它们的方法是在controller方法中验证它们。所以看起来应该是这样

@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设计中的单一职责吗?

1 个答案:

答案 0 :(得分:0)

是的,当然!这是一个好方法:类的单一责任-控制器负责处理数据,验证器-验证数据;开闭原理-验证数据无法通过控制器的方法更改; Liskov原则与基本的OOP原则相关联-验证器是独立的实体,无需任何其他操作即可更改为另一个;接口隔离很清晰,没有任何描述(完全分离的类); Depency Inversion也可以理解-使用注释接口,控制器对它的实现一无所知。因此,从意识形态和语言语法上来说,这是一种非常好的方法。

实施。

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

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

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