Pokuri
Pokuri

Reputation: 3082

Custom Jackson Deserializer to handle a property of any bean

I have a class called Channel which will have roles property as follows

public class Channel{
   private int id;
   private String roles;
}

And my JSON from client would be

{
 "id":"12345787654323468",
 "roles":[
          {"name":"admin","permissions":["can publish","can reject"]},
          {"name":"moderator","permissions":["can publish","can reject"]}
         ]
}

But when I convert this JSON to Channel object I am getting following exception

com.google.appengine.repackaged.org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.lang.String out of START_ARRAY token
 at [Source: java.io.StringReader@6d25f91; line: 1, column: 253] (through reference chain: com.pokuri.entity.Channel["roles"])

Now I want to deserialize this as a string into property roles of Channel class. Also can I write single custom deserializer to handle property of JSON array in any bean.

Upvotes: 2

Views: 1712

Answers (1)

Sachin Gupta
Sachin Gupta

Reputation: 8358

A custom Deserializer can do the trick here. :

class CustomDeserializer extends JsonDeserializer<String> {

    @Override
    public String deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JsonProcessingException {

        JsonNode node = jsonParser.readValueAsTree();       
        return node.toString();
    }

}

now to use this in your bean, you have to include it on roles field :

class Channel {
    private long id;

    @JsonDeserialize(using = CustomDeserializer.class)
    private String roles;



    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getRoles() {
        return roles;
    }

    public void setRoles(String roles) {
        this.roles = roles;
    }

}

Note : I have taken value of id as long as it was showing error for int, as value is too large in id attribute.

Now ObjectMapper can easily deserialize your JSON to Channel class :

String json = "{\"id\":\"12345787654323468\",\"roles\":[{\"name\":\"admin\",\"permissions\":[\"can publish\",\"can reject\"]},{\"name\":\"moderator\",\"permissions\":[\"can publish\",\"can reject\"]}]}";

ObjectMapper mapper = new ObjectMapper();
Channel channel = mapper.readValue(json, Channel.class);

System.out.println("Roles :"+channel.getRoles());

Upvotes: 4

Related Questions