Spring webflux bean 验证不工作

Spring webflux bean validation not working

我正在尝试在 Webflux 中使用 bean 验证。这是我目前所拥有的:

@PostMapping("contact")
fun create(@RequestBody @Valid contact: Mono<Contact>) : Mono<Contact> {
    return contact.flatMap { contactRepository.save(it) }
            .doOnError{ Error("test") }
}

验证无效...我希望显示 Error("test")...

有人有工作示例吗(Java 或 Kotlin)?

更新

这是一个存储库,因此可以复制它:https://github.com/jwz104/webflux-validation-test

要求:

curl --request POST \
  --url http://localhost:8080/tickets \
  --header 'content-type: application/json' \
  --data '{
    "email": "",
    "name": "",
    "message": ""
}'

将联系人重命名为工单,但一切仍然相同。

您还需要添加 bindingResult: BindingResult 作为额外参数。当该方法开始时,您可以执行类似 bindingResult.isValid() 的操作。我们在所有控制器方法上使用一个方面 return 向用户发送包含验证错误的错误消息。

您在示例项目中放置的注释实际上是Ticket class 的构造函数参数上的注释。对于 Spring 验证,您需要改为注释字段。您可以使用 annotation use-site targets 在 Kotlin 中执行此操作。

在此特定情况下,您的票证 class 应如下所示:

data class Ticket(
        @field:Id
        @field:JsonSerialize(using = ToStringSerializer::class)
        val id: ObjectId = ObjectId.get(),

        @field:Email
        @field:Max(200)
        @field:NotEmpty
        val email: String,

        @field:NotEmpty
        @field:Size(min = 2, max = 200)
        val name: String,

        @field:NotEmpty
        @field:Size(min = 10, max = 2000)
        val message: String
)

这将与以下控制器功能一起工作,并且会出现 return 预期的错误:

@PostMapping("tickets")
fun create(@RequestBody @Valid contact: Mono<Ticket>) : Mono<Ticket> {
    return contact.flatMap { ticketRepository.save(it) }
            .doOnError{ Error("test") }
}

我必须结合 SO 的一些答案才能使验证正确。 我所做的是:

  • 按照建议 class 制作了我的数据

    • 然后我用javax.validation.Validatorclass来验证数据 class.

import javax.validation.Validator import javax.validation.ConstraintViolationException

@Service
open class MyService {
    @Autowired
    lateinit var repository: UserRepository

    @Autowired
    lateinit var validator: Validator

     open fun createUser(user: User): Mono<User> {
         val violations = validator.validate(user)
          //if it violates our constraints, it will throw an exception, which we 
          //handle using global exception handler
          if(violations.isNotEmpty()){
               throw ConstraintViolationException(violations)
           }
           return repo.save(user)
         }
. . .
}
  • 在 application.properties 中添加这些行。
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

并捕获异常。

@RestControllerAdvice    
open class ExceptionHandlers {

  @ExceptionHandler(ConstraintViolationException::class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  fun throwConstraintViolationExcetion(ex: ConstraintViolationException): ApiResponse {
    return ApiResponse (message= ex.message.toString(), data= null);
  }
}

p.s ApiResponse只是一个以服务器消息和数据为参数的数据class。 无需处理 @Controller 中的错误,因为它会被 @Service class

抛出