objectmapper.readValue() 失败并出现错误“没有从字符串值反序列化的字符串参数构造函数/工厂方法”

Posted

技术标签:

【中文标题】objectmapper.readValue() 失败并出现错误“没有从字符串值反序列化的字符串参数构造函数/工厂方法”【英文标题】:objectmapper.readValue() fails with error "no String-argument constructor/factory method to deserialize from String value" 【发布时间】:2021-11-03 18:20:21 【问题描述】:

我的 objectmapper.readValue() 函数抛出一个错误,提示“无法构造 MyErrorMessage 的实例(尽管至少存在一个 Creator):没有字符串参数构造函数/工厂方法可以从字符串值反序列化。”

我的 MyErrorMessage 类有什么问题导致 objectmapper 失败?

这是我要解析的 JSON。


  "meta": 
    "id": "43225a4853b5497a",
    "time": "2020-06-03T13:36:03.391814Z"
  ,
  "datadetail": 
    "aKey": "hweriu-erw",
    "aTypes": [
      
        "bKey": "ewrf-7e9f",
        "cKey": "12ddf3",
        "status": "ERROR",
        "errorMessage": 
          "message": "Not found"
        
      
    ],
    "status": "ONE",
    "errorMessage": "ERROR with aKey"
  

这是函数和类。

private fun ParseResponse(responseMessage: String): MyResponse
    try 
        val objectMapper = ObjectMapper()
        return objectmapper.readValue(message, MyResponse::class.java)
    catch (e: JsonProcessingException) 
      throw IllegalArgumentException("json was invalid $responseMessage", e)
    


data class MyResponse(
    val meta: Metainfo,
    val datadetail: DataResponse
)

data class MetaInfo(
    val id: String,
    val time: Instant
)

data class DataResponse(
    val aKey: MyKey,
    val aTypes: List<TypesResponse>,

    val aNumber: String? = null,
    val status: StatusType,
    val errorMessage: MyErrorMessage = null
)

enum class StatusType
    OK,
    ERROR


data class TypesResponse(
    val bKey: MyBKey,
    val cKey: MyCKey,
    val status: StatusType,
    val errMessage: MyErrorMessage? = null
)

data class MyErrorMessage(
    @JsonProperty("message")
    val message: String,

    @JsonProperty("context")
    val context: MyContext?,
)
    constructor(message: String) : this(
        message = message,
        context = null
    )

    enum class MyContext
        ONE, TWO, THREE
    

【问题讨论】:

这是 Kotlin,不是 Java,对吧?如果还没有的话,你可能需要一个 Jackson Kotlin 模块 @GaëlJ 哦,是的,你是对的。我在帖子中修复了它。 Jackson Kotlin 模块已包含在内。 该代码甚至无法编译。 val context: MyContext?,enum class context 冲突。请编辑您的问题。 【参考方案1】:

您的 JSON 不遵循您的类结构。 你有"errorMessage": "ERROR with aKey",但你在DataResponse 中的errorMessage 实际上是一个MyErrorMessage,它是一个对象,而不是一个简单的字符串。

应该是:

"errorMessage": 
  "message": "ERROR with aKey"

如果这不是一个选项,那么您需要为您的MyErrorMessage 定制杰克逊 JSON 反序列化器来处理它。您可以查看示例here。

【讨论】:

注意这个"aTypes"的第一个元素里面的error的结构,而不是不是里面的error的结构"datadetail". @inconnu 似乎您不接受答案。有什么理由吗?你还需要帮助吗? @JoãoDias 抱歉,我误点击了。您的回答完全正确:) 再次感谢,我真的很感激!

以上是关于objectmapper.readValue() 失败并出现错误“没有从字符串值反序列化的字符串参数构造函数/工厂方法”的主要内容,如果未能解决你的问题,请参考以下文章

com.fasterxml.jackson.databind.ObjectMapper. .readValue .convertValue

jackson的objectMapper反序列化复杂对象TypeReference

json

Android - Jackson JSON 解析器在“发布”版本中返回空值

杰克逊:了解源JSON是数组还是对象

在 Java 中的 Jackson JSON 反序列化期间忽略丢失的属性