2016-03-29 19 views
1

Im folgende Beispiel, ich habe eine primären Klasse - A und seine Unterklasse - B. Sowohl als Eigenschaft in der allgemeinen Klasse X verwendet werden kannJackson Serialisierung für Subklassen

public class A 
{ 
    @JsonProperty("primary_key") 
    public final String primaryKey; 

    @JsonCreator 
    A(@JsonProperty("primary_key") String primaryKey) 
    { 
     this.primaryKey = primaryKey; 
    } 
} 
public class B extends A 
{ 
    @JsonProperty("secondary_key") 
    public final String secondaryKey; 

    @JsonCreator 
    B(@JsonProperty("primary_key") String primaryKey, @JsonProperty("secondary_key") String secondaryKey) 
    { 
     super(primaryKey); 
     this.secondaryKey = secondaryKey; 
    } 
} 

public class X 
{ 
    @JsonProperty("keys") 
    public final A keys; 

    @JsonCreator 
    X(@JsonProperty("keys") A keys) 
    { 
     this.keys = keys; 
    } 
} 

Wie kann ich Jackson verwenden polymorphe Merkmal, um korrekt die unten angegebenen json in ihre jeweiligen Klassen deserialisieren:

JSON A:

{ "keys" :{ 
       "primary_key" : "abc" 
      } 
} 

JSON B:

{ "keys" : { 
       "primary_key" : "abc", 
       "secondary_key" : "xyz" 
     } 
    } 

Erwartetes Ergebnis: Kartenschlüssel Objekt der Klasse A für JSON A und Klasse B für JSON B.

Bitte legen nahe, auch alternative Vorschläge.

+0

Ist nicht klar, was Ihr tatsächliches und erwartetes Ergebnis ist? –

+0

@ YusufK. Ich möchte den ersten JSON zu Klasse A und den zweiten JSON zu Klasse B zuordnen. – bin

+0

Ich denke, dass Sie Objekte von jedem gegebenen JSON erstellen möchten? –

Antwort

0

Wenn ich richtig unterbreche, funktioniert die Übergabe der Werte ohne Konfiguration. Ich glaube, das ist das, was Sie suchen:

public class Test { 

    private static final String JSON = "{\"keys\":{\"primary_key\":\"abc\",\"secondary_key\":\"xyz\"}}"; 

    public static void main(String[] args) throws IOException { 

     ObjectMapper mapper = new ObjectMapper(); 
     X x = mapper.readValue(JSON, X.class); 
     System.out.println(mapper.writeValueAsString(x)); 

    } 
} 

class A { 
    private String primary_key; 

    public String getPrimary_key() { 
     return primary_key; 
    } 

    public void setPrimary_key(String primary_key) { 
     this.primary_key = primary_key; 
    } 
} 

class B extends A { 

    private String secondary_key; 

    public String getSecondary_key() { 
     return secondary_key; 
    } 

    public void setSecondary_key(String secondary_key) { 
     this.secondary_key = secondary_key; 
    } 
} 

class X { 

    private B keys; 

    public B getKeys() { 
     return keys; 
    } 

    public void setKeys(B keys) { 
     this.keys = keys; 
    } 
} 

ausgegeben:

{"keys":{"primary_key":"abc","secondary_key":"xyz"}} 

Falls dies ist nicht das, was Sie erwarten, geben Sie bitte eine andere Erklärung, und ich werde die Antwort nach Bedarf bearbeiten.

+0

Wenn (Json enthält "secondary_key") dann Schlüssel Objekt in X sollte zu B gehören sonst Schlüssel Objekt in X sollte zu A gehören – bin

0

Es fühlt sich an wie ein ziemlich häufiges Problem und es gibt keine einfache Anmerkungen Weg, es zu lösen (oder vielleicht ich kann nicht ein nur finden):

Jackson Polymorphic Deserialization - Can you require the existence of a field instead of a specific value?

Deserializing polymorphic types with Jackson

Eine Sache, die Sie tun können besteht darin, Ihrem Objekt-Mapper einen benutzerdefinierten Deserializer hinzuzufügen. Hier ist schön Demo dieses Ansatzes: https://stackoverflow.com/a/19464580/1032167

Hier Demo zu Ihrem Beispiel verwandt:

import com.fasterxml.jackson.annotation.*; 
import com.fasterxml.jackson.core.JsonParser; 
import com.fasterxml.jackson.core.ObjectCodec; 
import com.fasterxml.jackson.databind.*; 
import com.fasterxml.jackson.databind.module.SimpleModule; 

import java.io.IOException; 

public class Main4 { 


private static final String jsonA = "{ \"keys\" : { \"primary_key\" : \"abc\" } }"; 
private static final String jsonB = 
     "{ \"keys\" : { \"primary_key\" : \"abc\", \"secondary_key\" : \"xyz\" } }"; 

public static void main(String[] args) throws IOException { 
    ObjectMapper mapper = new ObjectMapper(); 

    SimpleModule idAsRefModule = new SimpleModule("ID-to-ref"); 
    idAsRefModule.addDeserializer(A.class, new AJsonDeserializer()); 
    mapper.registerModule(idAsRefModule); 

    X tl = mapper.readValue(jsonA, X.class); 
    System.out.println(tl); 

    X t2 = mapper.readValue(jsonB, X.class); 
    System.out.println(t2); 
} 

public static class AJsonDeserializer extends JsonDeserializer<A>{ 

    @Override 
    public A deserialize(JsonParser jp, DeserializationContext dc) 
    throws IOException { 

     ObjectCodec codec = jp.getCodec(); 
     JsonNode node = codec.readTree(jp); 

     if (node.has("secondary_key")) { 
      return codec.treeToValue(node, B.class); 
     } 
     return new A(node.findValue("primary_key").asText()); 
    } 
} 

public static class A 
{ 
    @JsonProperty("primary_key") 
    public final String primaryKey; 

    @JsonCreator 
    A(@JsonProperty("primary_key") String primaryKey) 
    { 
     this.primaryKey = primaryKey; 
    } 

    @Override 
    public String toString() { 
     return "A{" + 
       "primaryKey='" + primaryKey + '\'' + 
       '}'; 
    } 
} 

public static class B extends A 
{ 
    @JsonProperty("secondary_key") 
    public final String secondaryKey; 

    @JsonCreator 
    B(@JsonProperty("primary_key") String primaryKey, 
     @JsonProperty("secondary_key") String secondaryKey) 
    { 
     super(primaryKey); 
     this.secondaryKey = secondaryKey; 
    } 

    @Override 
    public String toString() { 
     return "B{" + 
       "primaryKey='" + primaryKey + '\'' + 
       "secondaryKey='" + secondaryKey + '\'' + 
       '}'; 
    } 
} 

public static class X 
{ 
    @JsonProperty("keys") 
    public final A keys; 

    @JsonCreator 
    X(@JsonProperty("keys") A keys) 
    { 
     this.keys = keys; 
    } 

    @Override 
    public String toString() { 
     return "X{" + 
       "keys=" + keys + 
       '}'; 
    } 
} 
} 

Aber Sie müssen noch eine Super-Klasse erstellen, wenn Sie einen Deserializer Standard verwenden oder suchen hier, wie Sie das lösen können: https://stackoverflow.com/a/18405958/1032167

Verwandte Themen