如何反序列化 WWW 表单字段以在 Spring 中枚举?
How to deserialize WWW form field to enum in Spring?
我在 Kotlin 中尝试反序列化来自 WWW 表单的输入以枚举 Spring 应用程序中的 class 时遇到问题。
我的 DTO 和枚举 classes:
enum class Status(@get:JsonValue val value: Int) {
NORMAL(0),
ERROR(1);
companion object {
@JvmStatic
@JsonCreator
fun of(number: Int?): Status? {
return values().find { it.value == number }
}
}
}
data class RequestData(val status: Status?)
控制器的 POST 请求接收器方法:
@PostMapping("/post")
fun register(@Valid data: RequestData, error: Errors) {}
当我使用 Postman 通过 status = 0
发出 POST 请求时,请求失败并出现以下异常。
java.lang.IllegalArgumentException: Parameter specified as non-null is null: method com.example.Controller.post, parameter data
当我用 status = NORMAL
提出请求时,也不例外,但那是我不想要的。
我在 POST 请求中使用 application/x-www-form-urlencoded
内容类型。
请告诉我哪里做错了。
你就用这个名字吧。
ex) 状态 = 正常
value
重要吗?您可以使用序数
enum class Status{
NORMAL,
ERROR,
}
println(NORMAL.ordinal)
//result:0
这是个玩笑,但如果你需要
enum class Status(val value:String){
`0`("NORMAL"),`1`("ERROR")
}
println(data.status.value)
您可以为此使用 Converter class。请注意,请求参数我看起来像一个数字,但它们实际上是字符串。这就是下面的转换器接受 String?
和 returns Status?
的原因。这意味着,如果您的 enum
也接受它,对您来说会很方便。示例:NORMAL("0"), ERROR("1")
.
class ConvStringToStatus : Converter<String?, Status?> {
override fun convert(source: String?) = Status.of(source)
}
要使其正常工作,转换器必须如下注册。
@Configuration
class WebConfig : WebMvcConfigurer {
override fun addFormatters(registry: FormatterRegistry) {
registry.addConverter(ConvStringToStatus())
}
}
对于仍在寻找和找到它的任何人。如果您添加 jackson-module-kotlin
依赖项,示例代码可以工作并且不会抛出 non-null field is null
异常。它应该与您的 com.fasterxml.jackson.core
版本
匹配
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<version>2.9.8</version>
</dependency>
我在 Kotlin 中尝试反序列化来自 WWW 表单的输入以枚举 Spring 应用程序中的 class 时遇到问题。
我的 DTO 和枚举 classes:
enum class Status(@get:JsonValue val value: Int) {
NORMAL(0),
ERROR(1);
companion object {
@JvmStatic
@JsonCreator
fun of(number: Int?): Status? {
return values().find { it.value == number }
}
}
}
data class RequestData(val status: Status?)
控制器的 POST 请求接收器方法:
@PostMapping("/post")
fun register(@Valid data: RequestData, error: Errors) {}
当我使用 Postman 通过 status = 0
发出 POST 请求时,请求失败并出现以下异常。
java.lang.IllegalArgumentException: Parameter specified as non-null is null: method com.example.Controller.post, parameter data
当我用 status = NORMAL
提出请求时,也不例外,但那是我不想要的。
我在 POST 请求中使用 application/x-www-form-urlencoded
内容类型。
请告诉我哪里做错了。
你就用这个名字吧。
ex) 状态 = 正常
value
重要吗?您可以使用序数
enum class Status{
NORMAL,
ERROR,
}
println(NORMAL.ordinal)
//result:0
这是个玩笑,但如果你需要
enum class Status(val value:String){
`0`("NORMAL"),`1`("ERROR")
}
println(data.status.value)
您可以为此使用 Converter class。请注意,请求参数我看起来像一个数字,但它们实际上是字符串。这就是下面的转换器接受 String?
和 returns Status?
的原因。这意味着,如果您的 enum
也接受它,对您来说会很方便。示例:NORMAL("0"), ERROR("1")
.
class ConvStringToStatus : Converter<String?, Status?> {
override fun convert(source: String?) = Status.of(source)
}
要使其正常工作,转换器必须如下注册。
@Configuration
class WebConfig : WebMvcConfigurer {
override fun addFormatters(registry: FormatterRegistry) {
registry.addConverter(ConvStringToStatus())
}
}
对于仍在寻找和找到它的任何人。如果您添加 jackson-module-kotlin
依赖项,示例代码可以工作并且不会抛出 non-null field is null
异常。它应该与您的 com.fasterxml.jackson.core
版本
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<version>2.9.8</version>
</dependency>