2015-01-02 52 views
1

具有以下類:傑克遜TYPEID不產生JSON包括

public class BaseEntity<E> { 
    public TrackedChange<E> trackChange; 
} 


@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") 
@JsonSubTypes({ @JsonSubTypes.Type(value=B.class, name="b_type") }) 
public abstract class A extends BaseEntity<A> implements Cloneable{ 
    public String aFoo; 

    @Override 
    public Object clone() throws CloneNotSupportedException { 
     return super.clone(); 
    } 
} 

@JsonTypeName("b_type") 
public class B extends A { 
    public String bFoo; 
} 

public class TrackedChange<E> { 
    public E tracked; 
} 

public class Runner { 

    public static void main(String[] args) throws JsonProcessingException, CloneNotSupportedException { 

     B bInstance = new B(); 
     bInstance.bFoo = "bFoo"; 
     bInstance.aFoo = "aFoo"; 
     B clone = (B) bInstance.clone(); 
     bInstance.trackChange = new TrackedChange<A>(); 
     bInstance.trackChange.tracked = clone; 
     ObjectMapper mapper = new ObjectMapper(); 
     System.out.println(mapper.writeValueAsString(bInstance)); 
    } 
} 

生成的JSON是:

{ 
    "type":"b_type", 
    "trackChange":{ 
     "tracked":{ 
     "trackChange":null, 
     "aFoo":"aFoo", 
     "bFoo":"bFoo" 
     } 
    }, 
    "aFoo":"aFoo", 
    "bFoo":"bFoo" 
} 

類型未包含在trackChange.tracked對象("type":"b_type")信息。如何解決這個問題?

編輯:最後我用JsonTypeInfo.As.EXISTING_PROPERTY這是在2.3.0版本後引入的。它利用現有的屬性來確定實際的類型。

回答

1

類型擦除TrackedChange.tracked是你的問題。在運行時,您的類型由於類型擦除而丟失,並且Jackson序列化程序無法確定類型,因此無法將其識別爲B,並且找不到@JsonTypeInfo;因此在運行時傑克遜讀取TrackedChange.trackedObject

減少傑克遜類型刪除有各種方法,但他們通常干涉集合的泛型。

這裏只有一個辦法基本上實現自己的目標,我可以看到,你可以像這樣配置ObjectMapper:

ObjectMapper mapper = new ObjectMapper(); 
TypeResolverBuilder<?> typer = new ObjectMapper.DefaultTypeResolverBuilder(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE); 
typer = typer.init(JsonTypeInfo.Id.CLASS, null); 
typer = typer.inclusion(JsonTypeInfo.As.PROPERTY); 
typer = typer.typeProperty("type"); 
mapper.setDefaultTyping(typer); 

這將註冊序列化過程中的對象和非具體類型類型映射器配置(這涵蓋了TrackedChange.tracked的情況)。不幸的是,我沒有看到任何方式預先註冊這個配置將使用匹配的b_type名稱,如你的例子。最好的建議我是要改變你的類的配置使用以下,其行爲符合上述配置:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "type") 

給你這樣的輸出:

{ 
    "type" : "so.json.typeinfo.B", 
    "trackChange" : { 
    "tracked" : { 
     "type" : "so.json.typeinfo.B", 
     "trackChange" : null, 
     "aFoo" : "aFoo", 
     "bFoo" : "bFoo" 
    } 
    }, 
    "aFoo" : "aFoo", 
    "bFoo" : "bFoo" 
} 
+0

謝謝!我將JsonTypeInfo.Id.CLASS更改爲JsonTypeInfo.Id.NAME,並開始按預期工作! – tiktak