Десериализация JSON в объект с перегруженными методами, используя Джексона - PullRequest
52 голосов
/ 14 июня 2011

Я пытаюсь десериализовать объект JSON, хранящийся в CouchDb, используя Джексона. Этот объект необходимо десериализовать в pojo, который содержит перегруженные методы. Когда я пытаюсь извлечь объект с дивана и выполнить десериализацию, я получаю следующее исключение:

org.ektorp.DbAccessException: org.codehaus.jackson.map.JsonMappingException: Противоречивые определения для свойство «множитель»: com.db.commodities.framework.sdos.model.security.EqOpt # setMultiplier (1 params) против com.db.commodities.framework.sdos.model.security.EqOpt # setMultiplier (1 Титулы)

Я пытался комментировать сеттер, который хотел бы использовать Джексон, но, похоже, это не сработало.

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

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

Как мне настроить Джексона для правильной десериализации, используя определенный метод? Или я подхожу к этой проблеме неправильно?

EDIT:

Я внес следующие изменения. Кажется, это работает, но немного страшнее. Если у кого-то есть лучший способ сделать это, пожалуйста, не стесняйтесь поделиться, и я с удовольствием приму.

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

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

Ответы [ 3 ]

49 голосов
/ 14 июня 2011

Нет необходимости менять имя метода установки, чтобы избежать неоднозначности. В противном случае вы на правильном пути с @JsonIgnore. Если @JsonIgnore игнорировать все методы с одинаковыми именами, используемому методу не требуется аннотация @JsonProperty.

Вот простой пример, демонстрирующий эту точку.

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

Если вы не хотите изменять первоначальные определения POJO с помощью аннотации Джексона, тогда вы можете использовать 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);
}
6 голосов
/ 02 июня 2016

В Джексоне> 2,4 использовать напрямую:

mapper.addMixIn(Foo.class, IgnoreFooSetValueIntMixIn.class);
2 голосов
/ 26 сентября 2012

В случаях, когда @JsonIgnore не помогает (у меня в настоящее время есть такой случай, но я до сих пор не уверен в причине), вместо этого также можно использовать @XmlTransient.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...