简体   繁体   English

如何编写自定义的Jackson解串器,将包含原始json的json对象反序列化为单个对象?

[英]How do I write a custom Jackson deserializer to deserialize a json object that contains raw json into a single object?

Using the Jackson (>2.0) library, I would like to deserialize data that is coming from a backend that I do not control into a single object that contains the id of the wrapper as well as all of the data within the raw JSON string that is contained in the wrapper. 我想使用Jackson(> 2.0)库将来自我无法控制的后端的数据反序列化为单个对象,该对象包含包装程序的ID以及原始JSON字符串中的所有数据,包装中包含。 How would I write a custom Jackson deserializer to create a new object of Movie without defining a wrapper class? 我如何编写自定义的Jackson解串器来创建Movie的新对象而不定义包装类?

The data: 数据:

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

The data model: 数据模型:

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

My current deserializer looks like this: 我当前的解串器如下所示:

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)
    }
}

Note: My question is defined as Scala, but I think a Java approach would be similar enough as to not matter. 注意:我的问题定义为Scala,但我认为Java方法足够相似,没关系。 So an answer in Java would be acceptable. 因此,用Java回答是可以接受的。

Use JAXB. 使用JAXB。 It stands for Java API for XML Binding and is located in javax.xml.bind package. 它代表用于XML绑定的Java API,位于javax.xml.bind包中。

You will need the Eclipse MOXy provider as dependency. 您将需要Eclipse MOXy提供程序作为依赖项。 If you're doing Java EE programming, it is already there for you. 如果您正在执行Java EE编程,那么它已经为您服务。

Here's the implementation: 这是实现:

@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
    }

}

Next, take a look here how to actually do the unmarshalling. 接下来,在这里看看如何真正进行解组。

I found the answer! 我找到了答案! Another parser must be created to parse the raw json. 必须创建另一个解析器来解析原始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)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM