2

Say I have this JSON example:

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

I want to deserialize this into the following class:

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

The result I want is for the title to be deserialized as per normal but the json subtree under "custom" to be not deserialized and set as the raw json string:

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\" " +
        "}"                     +
    "}"); 

One other important note is that I can't change the original JSON under the custom node to use escaped json so it will be treated as a string.

Shane Rowatt
  • 1,951
  • 3
  • 27
  • 44

3 Answers3

3

I've found a little bit easier way. You can just add to your dto next setter:

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

and for getting as String simple annotate it with @JsonRawValue

katoquro
  • 326
  • 3
  • 9
2

You have to write new deserializer for your class. It could look like this:

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

Your Article class should look like this:

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

Now you can easily deserialize your JSON to Article class.

Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
  • Thanks a million. I ended up writing a Serializer that extended StdSerializer
    and a deserializer that extended StdDeserializer
    as this allowed me to wrap the Article in another generic type and still be able to read/write the json.
    – Shane Rowatt Oct 21 '13 at 04:00
  • FWIW: This in effect deserializes to a JsonNode and then serializes back to a string. Which may create json that is not 100% identical to the json originally submitted. – muttonUp Mar 11 '17 at 16:46
1

You can write a custom Deserializer .

Reference this SO question

Community
  • 1
  • 1
ssedano
  • 8,322
  • 9
  • 60
  • 98