问题描述
我在使用Bean Validation API验证Scala case类中的重写字段时遇到了问题。验证对于RestController中的@RequestParam
和@PathVariable
注解可以正常工作。
代码
RestController
@RestController
@Validated
@RequestMapping(value = Array("/my-endpoint")
class MyController(service: MyService) {
@GetMapping(Array("/{id}/{version}"))
def getByIds(
@PathVariable @Pattern(regexp = @Pattern(regexp = "^([A-Z]{3}):([A-Za-z]*):([0-9A-Za-z_\\-]*)$")) id: String,
@PathVariable @Pattern(regexp = @Pattern(regexp = "^([A-Z]{3}):([A-Za-z]*):([0-9A-Za-z_\\-]*)$")) version: String
): MyModel = getById(id, version)
@PostMapping
def create(@Valid @RequestBody entity: MyModel) ResponseEntity[Unit] = {
service.create(entity)
}
}
API模型/子类
@AvroNamespace(AvroSchemaBuilder.baseNamespace)
@Schema(description = "MyModel")
case class MyModel(
@NotNull
@Pattern(regexp = ValidationPattern.netexIdPattern)
@Schema(description = "Id", implementation = classOf[String], requiredMode = Schema.RequiredMode.REQUIRED)
override val id: String,
@Pattern(regexp = ValidationPattern.netexIdPattern)
@Schema(description = "Version", implementation = classOf[String], requiredMode = Schema.RequiredMode.REQUIRED)
override val version: String
) extends SomeClassC
超类
abstract class SomeClassC extends SomeClass B with SomeClassX {
}
abstract class SomeClass B extends SomeClassA {
val name: List[SomeObject]
val description: List[SomeObject]
}
abstract class SomeClassA {
val id: String
val version: String
}
安装
在单步执行代码之后,看起来RestController中的@Valid
注解被检测到并按预期进行了评估,而放置在模型类中的bean验证注解却没有。这让我相信这个类没有被Spring注册,因此没有暴露给bean验证API。这个假设可能是错误的,因为我可以看到org.hibernate.validator.internal.engine.ValidatorImpl
类中validateInContext
方法的valueContext
属性正确地引用了模型类-尽管所有相关的约束都是0
。
尝试解决方案
我尝试用@Component
注解model类和所有超类,以显式地将它们注册到Spring。但是,这会导致与模型中的两个覆盖变量相关的以下错误:
无法自动导丝。未找到“String”类型的Bean。
语言和框架版本
- Spring Boot
3.1.2
- Scala
2.13.11
- OpenJDK安装环境Temurin-
17.0.8+7
我在这件事上有点黔驴技穷了,所以非常感谢任何我能得到的帮助。
1条答案
按热度按时间olhwl3o21#
模型类中的以下调整就起到了作用:
解决方案是将
@field
注解添加到对给定字段设置的所有约束中。如果我理解正确的话,这是需要的“* 因为元注解用于告诉编译器实际字段应该被认为是注解的目标,而不是自动生成的访问器/修改器方法”*(来自另一个SO post的引用)