spring - 验证字段何时相互依赖
问题描述
我将请求对象名称传递Person
给控制器。假设该对象有 2 个两个字段。以下业务规则适用:
- 如果字段
age
的值 < 18,则该字段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 设计中的单一责任?
解决方案
是的当然!这是一个很好的方法:类的单一职责 - 控制器负责处理数据,验证器 - 用于验证数据;开闭原则——经过验证的数据是不能通过控制器的方法改变的;Liskov 原则与基本 OOP 原则相关 - 验证器是独立的实体,无需任何额外操作即可更改为另一个;接口隔离清晰,没有任何描述(完全分离的类);依赖倒置也是可以理解的——使用注解接口,控制器对其实现一无所知。所以,从意识形态和语言语法来看,这是一个非常好的方法。
执行。
- 创建类级
@interface
. 所有字段均可访问。 - 创建
ConstraintValidator
具有验证逻辑的类。 @RequestBody
在控制器方法中设置此注解。- 为控制器添加验证功能:
@Validated
控制器类和控制器方法@Valid
中的@RequestBody
实体。
如果您需要处理验证异常,只需抛出一个新异常并在@ControllerAdvise
类中处理,无需在验证或控制器类中处理代码。
官方资源中创建类级验证器的示例。
推荐阅读
- couchbase - Couchbase 使用 N1QL 编辑文档
- javascript - 带有 await Promise.all() 的代码不会继续执行
- python - 所有字符串列表到一个 numpy 浮点数组
- ios - 如何使用 Stencil 和 Cover 方法用金属 ios 绘制 SVG?
- docker - 使用 Docker 密钥访问 Jenkinsfile 中的数据库
- android - 谷歌地图插件在显示时会导致 Flutter 应用崩溃
- twine-game-engine - Sugarcube 使随机图像出现
- python - 在 pyomo 中创建具有稀疏索引的变量
- java - Java应用程序:连接到私人比特币节点的问题
- c# - 将枚举添加到特定类 c# 的列表中