Spring Rest 验证 ObjectNode 数据大小限制

huangapple go评论65阅读模式
英文:

Spring Rest Validation ObjectNode data size limit

问题

我有一个带有令牌创建调用的REST控制器。在这里,我在ObjectNode中获取到了大型JSON数据。数据库列是varchar2(4000),我想在控制器级别添加验证来限制这个ObjectNode的大小为4000。不确定如何做这个?

data class TokenRequest(
    @NotEmpty(message = "id is mandatory")
    open val id: String,
    @NotEmpty(message = "gameId is mandatory")
    open val game: String,
    @NotEmpty(message = "gameType is mandatory")
    open val type: String,
    @NotEmpty(message = "gameDate is mandatory")
    open val date: String,
    @NotEmpty(message = "coupon is mandatory")
    open val token: ObjectNode,
)

class TokenController {
    fun createToken(@Valid @RequestBody request: TokenRequest): Token {
        val now = Token.generateNowTimestamp()
        val token = Token.fromTokenRequest(request, now, now, request.teamId)
        return tokenService.create(token)
    }
}
英文:

I have rest controller with token creation call. Here inside ObjectNode I get big json data. The database column is varchar2(4000) nad I want limit this ObjectNode size to 4000 adding validation at controller level. Not sure how to do this?

data class TokenRequest(
    @NotEmpty(message = "id is mandatory")
    open val id: String,
    @NotEmpty(message = "gameId is mandatory")
    open val game: String,
    @NotEmpty(message = "gameType is mandatory")
    open val type: String,
    @NotEmpty(message = "gameDate is mandatory")
    open val date: String,
    @NotEmpty(message = "coupon is mandatory")
    open val token: ObjectNode,
)
class TokenController {
fun createToken(@Valid @RequestBody request: TokenRequest): Token {
        val now = Token.generateNowTimestamp()
        val token = Token.fromTokenRequest(request, now, now, request.teamId)
        return tokenService.create(token)
    }
}

答案1

得分: 2

这听起来像是你试图限制请求中“token”字段中包含的JSON数据大小。你希望它不超过4000个字符,对吗?实际上,你可以通过在Kotlin中创建自己的验证注解来处理这个问题。以下是如何操作的:

首先,你需要创建注解本身:

@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Constraint(validatedBy = [JsonNodeLengthValidator::class])
annotation class MaxJsonLength(
    val message: String = "JSON Object is too big",
    val groups: Array<KClass<*>> = [],
    val payload: Array<KClass<out Payload>> = [],
    val value: Int = 4000
)

接下来,我们将创建一个自定义的验证器:

import com.fasterxml.jackson.databind.node.ObjectNode
import javax.validation.ConstraintValidator
import javax.validation.ConstraintValidatorContext

class JsonNodeLengthValidator : ConstraintValidator<MaxJsonLength, ObjectNode> {

    private var maxLength: Int = 0

    override fun initialize(annotation: MaxJsonLength) {
        this.maxLength = annotation.value
    }

    override fun isValid(node: ObjectNode?, context: ConstraintValidatorContext): Boolean {
        return node?.toString()?.length ?: 0 <= maxLength
    }
}

最后,在你的数据类中使用我们新创建的验证注解:

data class TokenRequest(
    @NotEmpty(message = "id is mandatory")
    open val id: String,
    @NotEmpty(message = "gameId is mandatory")
    open val game: String,
    @NotEmpty(message = "gameType is mandatory")
    open val type: String,
    @NotEmpty(message = "gameDate is mandatory")
    open val date: String,
    @NotEmpty(message = "coupon is mandatory")
    @MaxJsonLength(value = 4000, message = "Token JSON object is too big")
    open val token: ObjectNode,
)

这样做可以确保,如果“token”的JSON字符串超过4000个字符,你的TokenRequest验证将失败。如果超过了,你将收到一个验证错误。希望这对你有所帮助!

英文:

It sounds like you're trying to cap the size of the JSON data contained in the 'token' field of your request. You want it to be no more than 4000 characters, right? There's actually a way to handle this in Kotlin by creating your own validation annotation. Here's how:

First, you need to create the annotation itself:

@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Constraint(validatedBy = [JsonNodeLengthValidator::class])
annotation class MaxJsonLength(
    val message: String = &quot;JSON Object is too big&quot;,
    val groups: Array&lt;KClass&lt;*&gt;&gt; = [],
    val payload: Array&lt;KClass&lt;out Payload&gt;&gt; = [],
    val value: Int = 4000
)

Then, we'll make a custom validator for it:

import com.fasterxml.jackson.databind.node.ObjectNode
import javax.validation.ConstraintValidator
import javax.validation.ConstraintValidatorContext

class JsonNodeLengthValidator : ConstraintValidator&lt;MaxJsonLength, ObjectNode&gt; {

    private var maxLength: Int = 0

    override fun initialize(annotation: MaxJsonLength) {
        this.maxLength = annotation.value
    }

    override fun isValid(node: ObjectNode?, context: ConstraintValidatorContext): Boolean {
        return node?.toString()?.length ?: 0 &lt;= maxLength
    }
}

Finally, we'll use our shiny new validator annotation in your data class:

data class TokenRequest(
    @NotEmpty(message = &quot;id is mandatory&quot;)
    open val id: String,
    @NotEmpty(message = &quot;gameId is mandatory&quot;)
    open val game: String,
    @NotEmpty(message = &quot;gameType is mandatory&quot;)
    open val type: String,
    @NotEmpty(message = &quot;gameDate is mandatory&quot;)
    open val date: String,
    @NotEmpty(message = &quot;coupon is mandatory&quot;)
    @MaxJsonLength(value = 4000, message = &quot;Token JSON object is too big&quot;)
    open val token: ObjectNode,
)

So there you have it! This makes sure that your TokenRequest validation will fail if the JSON string of token goes beyond 4000 characters. If it does, you'll get a validation error. Hope this helps!

huangapple
  • 本文由 发表于 2023年6月1日 19:54:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76381596.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定