如何解析json但将一个特定节点序列化为字符串?

时间:2013-10-17 23:06:58

标签: json jackson json-deserialization

说我有这个JSON示例:

{
    "title" : "tttt",
    "custom" : {
        "a" : "aaaaa",
        "b" : "bbbbb",
        "c" : { 
            "d" : "dddd"
        }
    }
}

我想将其反序列化为以下类:

public class Article {
    private String title;
    private String custom;

    public void setTitle(String title) { this.title = title; }
    public String getTitle() { return title; }
    public void setCustom(String custom) { this.custom = custom; }
    public String getCustom() { return custom; }        
}

我想要的结果是按照正常情况反序列化标题,但是“custom”下的json子树不反序列化并设置为原始json字符串:

ObjectMapper mapper = new ObjectMapper();
Article article = mapper.readValue(content, Article.class);
assertEquals(article.getTitle(), "tttt");
assertEquals(article.getCustom(),
   "{\"a\" : \"aaaaa\","        +
        "\"b\" : \"bbbbb\","    +
        "\"c\" : {"             + 
            "\"d\" : \"dddd\" " +
        "}"                     +
    "}"); 

另一个重要的注意事项是我无法在自定义节点下更改原始JSON以使用转义的json,因此它将被视为字符串。

3 个答案:

答案 0 :(得分:2)

您必须为您的班级编写新的反序列化程序。它看起来像这样:

class ArticleJsonDeserializer extends JsonDeserializer<Article> {

    @Override
    public Article deserialize(JsonParser parser, DeserializationContext context)
            throws IOException, JsonProcessingException {
        RawArticle rawArticle = parser.readValueAs(RawArticle.class);

        return rawArticle.toArticle();
    }

    private static class RawArticle {
        public String title;
        public JsonNode custom;

        Article toArticle() {
            Article article = new Article();
            article.setTitle(title);
            article.setCustom(custom.toString());

            return article;
        }
    }
}

您的Article课程应如下所示:

@JsonDeserialize(using = ArticleJsonDeserializer.class)
class Article {
   ....
}

现在,您可以轻松地将JSON反序列化为Article类。

答案 1 :(得分:2)

我发现了一些更简单的方法。你可以添加到你的dto下一个setter:

public void setCustom(JsonNode custom) { this.custom = custom.toString(); }

和获取字符串简单用@JsonRawValue

注释它

答案 2 :(得分:1)

您可以撰写自定义Deserializer

参考此SO question