使用Jackson重载方法将JSON反序列化为对象

gre*_*ker 52 java json jackson

我试图使用Jackson反序列化存储在CouchDb中的JSON对象.此对象需要反序列化为包含重载方法的pojo.当我尝试从沙发中检索对象并进行反序列化时,我得到以下异常:

org.ektorp.DbAccessException:org.codehaus.jackson.map.JsonMappingException:属性"multiplier"的冲突setter定义:com.db.commodities.framework.sdos.model.security.EqOpt #setMultiplier(1 params)vs com.db .commodities.framework.sdos.model.security.EqOpt #setMultiplier(1 params)

我试图注释我希望杰克逊使用的二传手,但这似乎没有用.

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

public void setMultiplier(double multiplier) {
     this.multiplier.setValue(String.valueOf(multiplier));
}
Run Code Online (Sandbox Code Playgroud)

如何配置Jackson以使用特定方法正确反序列化?或者我是以错误的方式处理这个问题?

编辑:

我做了以下更改.这似乎有效,但有点丑陋.如果有人有更好的方法来做到这一点,请随意分享,我很乐意接受.

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

@JsonIgnore
public void setMultiplier(double multiplier) {
    this.multiplier.setValue(String.valueOf(multiplier));
}
Run Code Online (Sandbox Code Playgroud)

Pro*_*uce 49

没有必要更改setter方法的名称以避免歧义.你正处于正确的轨道上@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));
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您不想使用Jackson注释更改原始POJO defs,那么您可以使用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);
}
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案似乎忽略了两个`setValue`属性(即,即使JSON包含一个值,也没有任何设置).原来你*需要`@JsonProperty("value")`你要保留的那个. (5认同)
  • 当你不能改变课程,当它是第三方时怎么办?有没有办法呢? (4认同)
  • 截至杰克逊1.9,此解决方案不再有效.任何setter/getter/associated字段上的`@JsonIgnore`都会对该属性应用相同的内容. (4认同)
  • 使用jackson 1.9,我只需要在正确的setter上使用`@JsonProperty("value")`(在重载的setter上没有`@JsonIgnore`). (3认同)
  • 使用Jackson 2.4,在setter上只使用@JsonIgnore被忽略*确实*有效. (2认同)

小智 6

在Jackson> 2.4中直接使用:

mapper.addMixIn(Foo.class, IgnoreFooSetValueIntMixIn.class);
Run Code Online (Sandbox Code Playgroud)