2011-06-14 13 views
44

我试图使用Jackson反序列化存储在CouchDb中的JSON对象。该对象需要反序列化成包含重载方法的pojo。当我尝试检索沙发上的对象,做反序列化,我得到以下异常:将JSON反序列化到使用Jackson重载方法的对象中

org.ektorp.DbAccessException: org.codehaus.jackson.map.JsonMappingException: 为 物业冲突的二传手定义“乘数“: 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)); 
} 

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

编辑:

我已经做了如下修改。这似乎工作,但有点丑陋。如果有人有更好的方式做到这一点,请随时分享,我会很乐意接受。

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

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

是的,这是有效的修补。我同意如果推断被使用,如果只明确指出一种替代方案,其他人可以在过度模糊的情况下被忽略 - 我可以为此添加Jira功能请求。 – StaxMan 2011-06-15 20:57:20

+0

另一件事 - 有趣的是,这里有一个过载问题,因为杰克逊确实允许有限的超载。具体来说,如果参数是int或long(而不是double),则不会发生问题。但是不支持其他基本类型(double,float,boolean,char,byte,short);尽管浮动和双重可能应该是。使用int和long差异基于JSON的含义解析 - JSON对象使用POJO setter; JSON数字为int或long。 – StaxMan 2011-06-15 21:04:53

回答

43

没有必要更改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)); 
    } 
} 

如果你不想改变与杰克逊注释原始POJO DEFS,那么你可以使用一个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); 
} 
+0

谢谢,这正是我正在寻找的。 – gregwhitaker 2011-06-14 23:00:41

+0

当你不能改变班级,什么时候是第三方时呢?有没有一种方法呢? – crunchdog 2013-01-23 12:15:23

+1

杰克逊的混音设施可能很适合您的需求。它允许您有效地注释第三方类型定义,而不会更改原件。 – 2013-01-23 16:23:42

2

在情况下@JsonIgnore没有帮助(我现在有这样的情况,但我仍不能确定的原因),也可以使用@XmlTransient代替。

3

在杰克逊> 2.4直接使用:

mapper.addMixIn(Foo.class, IgnoreFooSetValueIntMixIn.class); 
相关问题