web-dev-qa-db-fra.com

Désérialisation de JSON en objet avec des méthodes surchargées à l'aide de Jackson

J'essaie de désérialiser un objet JSON stocké dans CouchDb en utilisant Jackson. Cet objet doit être désérialisé en un pojo contenant des méthodes surchargées. Lorsque j'essaie de récupérer l'objet du canapé et de faire la désérialisation, j'obtiens l'exception suivante:

org.ektorp.DbAccessException: org.codehaus.jackson.map.JsonMappingException: définitions de setter conflictuelles pour la propriété "multiplicateur": com.db.commodities.framework.sdos.model.security.EqOpt # setMultiplier (1 params) vs com.db .commodities.framework.sdos.model.security.EqOpt # setMultiplier (1 params)

J'ai essayé d'annoter le setter que j'aimerais que Jackson utilise, mais cela ne semble pas avoir fonctionné.

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

public void setMultiplier(double multiplier) {
     this.multiplier.setValue(String.valueOf(multiplier));
}

Comment configurer Jackson pour désérialiser correctement en utilisant une méthode spécifique? Ou est-ce que j'aborde ce problème dans le mauvais sens?

MODIFIER:

J'ai apporté les modifications suivantes. Cela semble fonctionner, mais c'est un peu plus laid. Si quelqu'un a une meilleure façon de le faire, n'hésitez pas à partager et j'accepterai volontiers.

@JsonProperty("multiplier")
protected void setMultiplierAttribute(SDOSAttribute multiplier) {
    this.multiplier = multiplier;
}

@JsonIgnore
public void setMultiplier(double multiplier) {
    this.multiplier.setValue(String.valueOf(multiplier));
}
52
gregwhitaker

Il n'est pas nécessaire de changer le nom de la méthode setter pour éviter toute ambiguïté. Vous êtes autrement sur la bonne voie avec @JsonIgnore. Avec @JsonIgnore sur toutes les méthodes portant le même nom à ignorer, celle à utiliser n'a pas besoin de @JsonProperty annotation.

Voici un exemple simple pour démontrer ce 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));
  }
}

Si vous ne souhaitez pas modifier les définitions POJO vierges avec une annotation Jackson, vous pouvez utiliser un 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);
}
49
Programmer Bruce

Dans Jackson> 2.4, utilisez directement:

mapper.addMixIn(Foo.class, IgnoreFooSetValueIntMixIn.class);
6
gribo

Dans les cas où @JsonIgnore n'aide pas (j'ai actuellement un tel cas, mais je ne suis toujours pas sûr de la raison), il est également possible d'utiliser @XmlTransient à la place.

2
lilalinux