Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserializing JSON into object with overloaded methods using Jackson

Tags:

java

json

jackson

I am attempting to deserialize a JSON object stored in CouchDb using Jackson. This object needs to deserialize into a pojo that contains overloaded methods. When I attempt to retrieve the object from couch and do the deserialization I get the following exception:

org.ektorp.DbAccessException: org.codehaus.jackson.map.JsonMappingException: Conflicting setter definitions for property "multiplier": com.db.commodities.framework.sdos.model.security.EqOpt#setMultiplier(1 params) vs com.db.commodities.framework.sdos.model.security.EqOpt#setMultiplier(1 params)

I tried to annotate the setter I would like Jackson to use, but that appears to not have worked.

@JsonProperty("multiplier") public void setMultiplier(SDOSAttribute multiplier) {      this.multiplier = multiplier; }  public void setMultiplier(double multiplier) {      this.multiplier.setValue(String.valueOf(multiplier)); } 

How do I configure Jackson to properly deserialize using a specific method? Or am I approaching this problem the wrong way?

EDIT:

I have made the following changes. This seems to work, but is a little uglier. If anyone has a better way to do this please feel free to share and I will gladly accept.

@JsonProperty("multiplier") protected void setMultiplierAttribute(SDOSAttribute multiplier) {     this.multiplier = multiplier; }  @JsonIgnore public void setMultiplier(double multiplier) {     this.multiplier.setValue(String.valueOf(multiplier)); } 
like image 870
gregwhitaker Avatar asked Jun 14 '11 15:06

gregwhitaker


People also ask

Which methods does Jackson rely upon to deserialize a JSON formatted string?

The readValue() method is used to parse (deserialize) JSON from a String, Stream, or File into POJOs. On the other hand, the writeValue() method is used to turn POJOs into JSON (serialize).

What is JsonProperty annotation in spring boot?

The @JsonProperty annotation is used to map property names with JSON keys during serialization and deserialization. By default, if you try to serialize a POJO, the generated JSON will have keys mapped to the fields of the POJO.

What does Jackson ObjectMapper do?

The Jackson ObjectMapper can parse JSON from a string, stream or file, and create a Java object or object graph representing the parsed JSON. Parsing JSON into Java objects is also referred to as to deserialize Java objects from JSON. The Jackson ObjectMapper can also create JSON from Java objects.

What is Jackson deserialization?

Deserialization annotations are used when we deserialize JSON string into an Object. Jackson library provides several deserialization annotations such as @JsonCreator, @JacksonInject, @JsonAnySetter, etc. These annotations are mostly used in setter.


2 Answers

It's not necessary to change the name of the setter method to avoid ambiguity. You're otherwise on the right track with @JsonIgnore. With @JsonIgnore on all of the same-named methods to be ignored, the one to use does not need the @JsonProperty annotation.

Here's a simple example to demonstrate this point.

input.json: {"value":"forty-two"}

Foo.java:

import java.io.File;  import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.map.ObjectMapper;  public class Foo {   String value;    public String getValue() {return value;}   public void setValue(String value) {this.value = value;}    @JsonIgnore   public void setValue(int value) {this.value = String.valueOf(value);}    public static void main(String[] args) throws Exception   {     ObjectMapper mapper = new ObjectMapper();     Foo foo = mapper.readValue(new File("input.json"), Foo.class);     System.out.println(mapper.writeValueAsString(foo));   } } 

If you don't want to alter the pristine POJO defs with a Jackson annotation, then you can use a MixIn.

import java.io.File;  import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.map.ObjectMapper;  public class Foo {   String value;    public String getValue() {return value;}   public void setValue(String value) {this.value = value;}   public void setValue(int value) {this.value = String.valueOf(value);}    public static void main(String[] args) throws Exception   {     ObjectMapper mapper = new ObjectMapper();     mapper.getDeserializationConfig().addMixInAnnotations(Foo.class, IgnoreFooSetValueIntMixIn.class);     Foo foo = mapper.readValue(new File("input.json"), Foo.class);     System.out.println(mapper.writeValueAsString(foo));   } }  abstract class IgnoreFooSetValueIntMixIn {   @JsonIgnore public abstract void setValue(int value); } 
like image 149
Programmer Bruce Avatar answered Sep 21 '22 06:09

Programmer Bruce


In Jackson > 2.4 use directly :

mapper.addMixIn(Foo.class, IgnoreFooSetValueIntMixIn.class); 
like image 21
gribo Avatar answered Sep 21 '22 06:09

gribo