当前位置: 首页 > 知识库问答 >
问题:

Kotlin和Spring Boot请求正文验证

白飞飙
2023-03-14

我刚开始使用kotlin和Spring Boot开发一个简单的web应用程序。

让我们以一个简单的数据类对象为例

@Entity  
data class User (name: String) {  
  @Id @GeneratedValue(strategy = GenerationType.AUTO)  
  var id: Long = -1  
}  
@RequestMapping(method = arrayOf(RequestMethod.POST))
fun createUser (@RequestBody user: User): User {
    return userService.createUser(user)
}

好吧,使用任何请求体发出请求只会抛出http 400错误没有找到合适的构造函数,无法从对象值反序列化(缺少默认构造函数或创建者,或者可能需要添加/启用类型信息?);嵌套异常是com.fasterxml.jackson.databind.jsonMappingException

为了消除这个错误,我发现我们需要为构造函数参数提供一些默认值,如下所示:

name: String = ""

或者也许:

name: String? = null

在这个示例中,只有一个参数,但是手动使用较大的类似乎不是一个好方法

提前致谢

共有1个答案

杜翰林
2023-03-14

我认为以下由两部分组成的解决方案可以在Spring Boot2.x:

@Configuration
class ValidationRouter(
        val validationService: ValidationService
) {

    @Bean
    fun router() = router {
        accept(APPLICATION_JSON).nest {
            "/api".nest {
                POST("/validation") { req ->
                    req.bodyToMono(ValidatingBody::class.java)
                            .doOnNext(validationService::validate)
                            .flatMap { ServerResponse.ok().build() }
                            .onErrorResume(BodyValidationException::class.java, validationService::handle)
                }
            }

        }

    }

    data class ValidatingBody(
            @get:NotBlank(message = "should not be blank")
            var mandatoryText: String?,
            @get:Size(min = 2, max = 10, message = "should contain more than 2 and less than 10 characters")
            @get:NotBlank(message = "should not be blank")
            var sizedText: String?,
            @get:Min(value = 1, message = "should be no less than 1")
            @get:Max(value = 10, message = "should be no greater than 10")
            @get:NotNull(message = "should be specified")
            var limitedNumber: Int?
    )
}
@Service
class ValidationService(val validator: Validator) {

    private val log = LoggerFactory.getLogger(ValidationService::class.java)

    @Throws(BodyValidationException::class)
    fun <T> validate(o: T) {
        val violations = validator.validate(o)
        if (violations.isEmpty()) return

        throw BodyValidationException.of(violations.stream()
                .map { v: ConstraintViolation<T> -> "${v.propertyPath} ${v.message}" }
                .collect(Collectors.toSet()).toMutableSet())
    }

    fun handle(e: BodyValidationException): Mono<ServerResponse> =
            handleInternal(ErrorResponse(e.errors))

    private fun handleInternal(response: ErrorResponse): Mono<ServerResponse> =
            Mono.just(response)
                    .doOnNext { res -> log.warn(res.errors.joinToString(",")) }
                    .flatMap { res ->
                        badRequest().contentType(APPLICATION_JSON)
                                .bodyValue(res)
                    }

    data class ErrorResponse(val errors: Set<String>)

    class BodyValidationException private constructor(var errors: Set<String>) : IllegalArgumentException() {
        companion object {
            fun of(errors: Set<String>): BodyValidationException {
                return BodyValidationException(errors)
            }
        }

    }
}
 类似资料:
  • 我们正在使用JAX RS为我们的一个项目实现一个REST API。要求是用户将以JSON格式传入请求对象。 让我们假设我们有一个在命中APIendpoint时调用的方法 示例请求对象: { “firstName”:“Test”, “lastName”:“Name”, “sno”:“A123” } 吸气剂和setter 现在,如果用户尝试向上面给出的请求对象添加其他参数(例如:“age”)并调用ap

  • 我有一个REST API使用POST调用来创建记录,我希望在POST调用中传递某些对象,如果缺少任何东西,我必须直接拒绝它们的唯一, 但是,当使用丢失的属性进行Post调用时,我可以在MongoDB中创建一个条目,我不想保留它,因为这不是一个正确的请求,@validation对我来说不起作用,我正在使用spring boot 2.0.6和MongoDB 4.0.4,任何帮助都非常感谢。提前感谢

  • 有没有办法在spring boot中验证补丁请求主体? 如果任何用户发送请求时,“op”(字段)为“xx”,而“path”(字段)为“se”。有没有办法在不更改合同的情况下验证它并抛出400(错误的请求)?

  • 在我的请求正文中,几乎没有JSON原始数据中需要的参数,我希望在Postman中的请求前脚本中验证这些参数是否存在于正文中。 如何检查请求正文中是否传递了和?

  • 如何在处理正文请求之前验证身份验证? 我正在使用vertx: 我想在处理正文请求之前验证身份验证。但我得到了错误的java。lang.IllegalStateException:请求已被读取 使用暂停功能上的延迟复制: 当运行delay(100)时(这是验证过程的示例),我得到了上面的错误。如果我对延迟(100)进行注释,它可以正常工作。

  • 我想用注释验证我的请求体,但是它在Spring Boot中不起作用 我在JAR文件中有一个请求类,我不能用两个字段来修改它。一个字段的类型为Object。我的控制器类接受这个类对象作为请求主体。当我将下面的JSON传递给控制器时,验证不起作用。下面是代码示例。 请求类: 另一类: 控制器类: 呼叫代码设置请求如下: 这是我发出的请求: 超过64个字符的firstName: 示例JSON: 如果不包