如何在Sping Boot 3中为具有多层继承的Scala case class设置bean验证?

lp0sw83n  于 7个月前  发布在  Scala
关注(0)|答案(1)|浏览(71)

问题描述

我在使用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

我在这件事上有点黔驴技穷了,所以非常感谢任何我能得到的帮助。

olhwl3o2

olhwl3o21#

模型类中的以下调整就起到了作用:

@AvroNamespace(AvroSchemaBuilder.baseNamespace)
@Schema(description = "MyModel")
case class MyModel(
  @(NotNull@field)
  @(Pattern@field)(regexp = "^([A-Z]{3}):([A-Za-z]*):([0-9A-Za-z_\\-]*)$")
  @Schema(description = "Id", implementation = classOf[String], requiredMode = Schema.RequiredMode.REQUIRED) 
  override val id: String,

  @(NotNull@field)
  @(Pattern@field)(regexp = "^([A-Z]{3}):([A-Za-z]*):([0-9A-Za-z_\\-]*)$")
  @Schema(description = "Version", implementation = classOf[String], requiredMode = Schema.RequiredMode.REQUIRED)
  override val version: String
) extends SomeClassC

解决方案是将@field注解添加到对给定字段设置的所有约束中。如果我理解正确的话,这是需要的“* 因为元注解用于告诉编译器实际字段应该被认为是注解的目标,而不是自动生成的访问器/修改器方法”*(来自另一个SO post的引用)

相关问题