2016-05-17 5 views
0

Ich benutze Spring Boot mit Jackson, um eine API zur Verfügung zu stellen. In meiner Datenbank gibt es ein Generalisierungs-/Spezialisierungsfeld. Das heißt, ich habe zwei Felder: einen Wert und ein Feld, das den Datentyp des Wertes definiert.Jackson: Serialize eine EER Spezialisierung

So sieht mein Unternehmen dies wie:

public class Example{ 
    private String value; 
    private String type; 

    // getters and setters 
} 

Zum Beispiel mit diesen drei Einträge:

"1234";"Integer" 
"example string";"String" 
"true";"Boolean" 

Jackson diese Serialisierung wie folgt:

[{ 
    "value": "1234", 
    "type": "Integer" 
}, 
{ 
    "value": "example string", 
    "type": "String" 
}, 
{ 
    "value": "true", 
    "type": "Boolean" 
}] 

Dies ist, was ich expteced , aber ich brauche das:

[{ 
    "value": 1234, 
    "type": "Integer" 
}, 
{ 
    "value": "example string", 
    "type": "String" 
}, 
{ 
    "value": true, 
    "type": "Boolean" 
}] 

Also sollten die Werte entsprechend dem Wert des Feldes "type" serialisiert werden. Ich weiß, dass ich einen Serializer an das Feld "Wert" anhängen kann, aber ich kann nicht auf das Feld "Typ" dort zugreifen, um zu wissen, wie man den Wert serialisiert.

Antwort

1

Eine Möglichkeit ist, Ihr Beispiel Klasse wie folgt zu ändern, wenn Sie können:

public static class Example { 
    private String value; 
    private String type; 

    @JsonIgnore 
    public String getValue() { 
     return value; 
    } 

    @JsonProperty("value") 
    @JsonRawValue 
    public Object getRawValue() { 
     if("String" .equals(type)){ 
      return '"'+ value +'"'; 
     } 
     return value; 
    } 

    public void setValue(String value) { 
     this.value = value; 
    } 

    public String getType() { 
     return type; 
    } 

    public void setType(String type) { 
     this.type = type; 
    } 
} 

Oder Sie Deserializer auf Example Klasse

public static void main(String[] args) throws JsonProcessingException { 
    ObjectMapper mapper = new ObjectMapper(); 
    SimpleModule module = new SimpleModule(); 
    module.addSerializer(Example.class, new MySerializer()); 
    mapper.registerModule(module); 
    System.out.println(mapper.writeValueAsString(list)); 
} 

private static class MySerializer extends JsonSerializer<Example> { 
    @Override 
    public void serialize(Example value, JsonGenerator gen, SerializerProvider serializers) 
                     throws IOException { 
     gen.writeStartObject(); 

     gen.writeFieldName("value"); 

     if (value.getType().equals("String")) { 
      gen.writeString(value.getValue()); 
     } else { 
      gen.writeRawValue(value.getValue()); 
     } 

     gen.writeStringField("type", value.getType()); 
     gen.writeEndObject(); 
    } 
} 

Ergebnis verwenden:

[{"value":1234,"type":"Integer"},{"value":"example string","type":"String"},{"value":true,"type":"Boolean"}] 

aktualisieren

Hier ist eine Möglichkeit, wie Sie benutzerdefinierte Deserializer und Standard eine für jeden anderen Bereich verwenden:

private static class MySerializer extends JsonSerializer<Example> { 
    private static final ObjectMapper internalMapper = new ObjectMapper(); 

    @Override 
    public void serialize(Example value, JsonGenerator gen, SerializerProvider serializers) throws IOException { 
     ObjectNode node = internalMapper.valueToTree(value); 

     if (value.getType().equals("String")) { 
      node.put("value", value.getValue()); 
     } else { 
      node.putRawValue("value", new RawValue(value.getValue())); 
     } 

     gen.writeObject(node); 
    } 
} 

haben müssen @JsonIgnore in Ihrem public String getValue()

+0

Hallo! Dank dafür. Ist es auch möglich, das Standardverhalten für alle anderen Felder von "value" zu verwenden, ohne explizit festzulegen, wie mit jedem Feld umgegangen werden soll? Meine Entity hat viele Felder und ich möchte sie nicht in mehreren Klassen auflisten/verwalten (Entity, Serializer und Deserializer ...) – Indivon

+0

@Indivon Ich habe die Antwort mit der neuen Option aktualisiert und yep kann die Standard-Deserialisierung verwenden Ihr benutzerdefinierter Deserializer. Geben Sie mir eine Minute, ich werde die Informationen aktualisieren – varren

+0

@Indivon aktualisiert meinen Beitrag, werfen Sie einen Blick, wahrscheinlich gibt es einige andere Option, die Sie versuchen könnten – varren

Verwandte Themen