【问题标题】:How do I write a custom Jackson deserializer to deserialize a json object that contains raw json into a single object?如何编写自定义 Jackson 反序列化器以将包含原始 json 的 json 对象反序列化为单个对象?
【发布时间】:2017-01-11 05:59:10
【问题描述】:

使用 Jackson (>2.0) 库,我想将来自我无法控制的后端的数据反序列化为单个对象,该对象包含包装器的 id 以及原始数据中的所有数据包装器中包含的 JSON 字符串。在不定义包装类的情况下,如何编写自定义 Jackson 反序列化器来创建 Movie 的新对象?

数据:

{
  "id": "1",
  "rawMovieData": "{\"name\": \"Office Space\", \"director\": \"Mike Judge\"}"
}

数据模型:

case class Movie(id: String, name: String, director: String)

我当前的反序列化器如下所示:

class MovieDeserializer extends JsonDeserializer[Movie] {
    override def deserialize(jp: JsonParser, ctxt: DeserializationContext): Movie {
        val wrapper: JsonNode = jp.getCodec.readValue(jp)
        val id: String = wrapper.get("id").asInstanceOf[TextNode].textValue
        val rawMovie: String = wrapper.get("rawMovieData").asInstanceOf[TextNode].textValue
        //How do I now deserialize rawMovie?

        Movie(id, name, director)
    }
}

注意:我的问题被定义为 Scala,但我认为 Java 方法足够相似以至于无关紧要。因此,Java 中的答案是可以接受的。

【问题讨论】:

    标签: java json scala jackson deserialization


    【解决方案1】:

    使用 JAXB。它代表 用于 XML 绑定的 Java API 并且是 位于 javax.xml.bind 包。

    您将需要 Eclipse MOXy 提供程序作为依赖项。如果您正在进行 Java EE 编程,那么它已经为您准备好了。

    下面是实现:

    @XmlRootElement
    @XmlAccessorType(FIELD)
    public class Movie {
    
        @XmlElement
        private int id;
    
        @XmlElement
        private String rawMovieData;
    
        public Movie() {
            // must have a default constructor if you define a non-default
        }
    
    }
    

    接下来,看看here如何实际进行解组。

    【讨论】:

    • 你真的可以使用 JAXB 来解组 JSON 吗?
    • Yes,我整天都在这样做。您将需要 Eclipse MOXy jaxb 提供程序。
    • 虽然这对于寻求(取消)编组 JSON 的通用方法的人来说可能是一个很好的解决方案。这并没有解决我针对杰克逊图书馆的问题的性质。我已经在问题的正文中更清楚地说明了这一点。
    【解决方案2】:

    我找到了答案!必须创建另一个解析器来解析原始 json。

    class MovieDeserializer extends JsonDeserializer[Movie] {
        override def deserialize(jp: JsonParser, ctxt: DeserializationContext): Movie {
            val wrapper: JsonNode = jp.getCodec.readValue(jp)
            val id: String = wrapper.get("id").asInstanceOf[TextNode].textValue
            val rawMovie: String = wrapper.get("rawMovieData").textValue
    
            //Create a new parser to parse the raw json string
            val rawMovieParser: JsonParser = jp.getCodec.getFactory.createParser(rawMovie)
            val movieNode: JsonNode = rawMovieParser.getCodec.readValue(rawMovieParser)
            val name: String = movieNode.get("name").textValue
            val director: String = movieNode.get("director").textValue
    
            Movie(id, name, director)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-20
      • 2023-03-13
      • 1970-01-01
      • 2022-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多