gpt4 book ai didi

java - 使用 jacksonObjectMapper 将 JSON 反序列化为不同类型

转载 作者:行者123 更新时间:2023-12-02 10:53:47 25 4
gpt4 key购买 nike

假设我从服务器收到一个 JSON 错误,该错误可以采用两种不同的结构:

{"errorMessage": "This action is unauthorized."}

{"errorMessage":{"changePassword":"Old password is incorrect."}}

如何反序列化这种json?

我尝试过的

我尝试拥有抽象类“Error”和两个子类:

abstract class Error() {}

data class SingleError(val errorMessage: String) : Error()

data class MultiError(val errorMessage: Map<String, String>) : Error()

然后我尝试:

jacksonObjectMapper().readValue<Error>(response.body)

反序列化,但我有异常(exception):

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.fifth_llc.siply.main.request.Forbidden$Error` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: (String)"{"errorMessage":{"changePassword":"Old password is incorrect."}}"; line: 1, column: 1]

我也尝试过 JsonDeserialize annotaiton,但如果我想解析为具体类型,我似乎可以使用它:

@JsonDeserialize(`as` = MultiError::class)

有什么帮助吗?

最佳答案

自定义解串器方法:

sealed class Error() {
data class SingleError(val errorMessage: String) : Error()
data class MultiError(val errorMessage: Map<String, String>) : Error()
}
...
class ErrorDeserializer : StdDeserializer<Error>(Error::class.java) {

companion object {
private val MAP_TYPE_REFERENCE = object : TypeReference<Map<String, String>>() {}
}

@Throws(IOException::class, JsonProcessingException::class)
override fun deserialize(jp: JsonParser, ctxt: DeserializationContext): Error {
val mapper = jp.codec as ObjectMapper
val node: JsonNode = mapper.readTree(jp)
val msgNode = node.get("errorMessage")
if (msgNode.isValueNode) {
val errorMsg = msgNode.asText()
return Error.SingleError(errorMsg)
} else {
val errorMsgs = mapper.readValue<Map<String, String>>(msgNode.toString(),
MAP_TYPE_REFERENCE)
return Error.MultiError(errorMsgs)
}
}
}

用法:

val mapper = ObjectMapper()
val module = SimpleModule().addDeserializer(Error::class.java, ErrorDeserializer())
mapper.registerModule(module)

val error = mapper.readValue<Error>("json content", Error::class.java)
when (error) {
is Error.SingleError -> {
// error.errorMessage
}
is Error.MultiError -> {
// error.errorMessage
}
}

关于java - 使用 jacksonObjectMapper 将 JSON 反序列化为不同类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51943696/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com