2016-07-08 11 views
2

Ich habe ein Wertobjekt mit einem Optional<Integer> Feld. Ich möchte, dass es wie eine Zeichenfolge aussieht, wenn es serialisiert ist, aber der Optional Teil ist in die Quere kommen.Mit Jackson, um eine Guava optional zu serialisieren <Integer> als eine Zeichenfolge

Ich habe die folgende Klasse:

public class Person { 
    private com.google.common.base.Optional<Integer> age; 
    public com.google.common.base.Optional<Integer> getAge() { 
     return age; 
    } 
    public void setAge(Integer age) { 
     this.age = com.google.common.base.Optional.fromNullable(age); 
    } 
} 

Hier ist mein Test:

@Test 
public void testPerson() throws Exception { 
    ObjectMapper objectMapper = new ObjectMapper().registerModule(new GuavaModule()); 
    Person person = new Person(); 
    person.setAge(1); 
    String jsonString = objectMapper.writeValueAsString(person); 
    assertEquals(jsonString, "{\"age\":\"1\"}"); 
} 

Es ist mit diesem Ausgang versagt:

java.lang.AssertionError: expected [{"age":"1"}] but found [{"age":1}]

Ich habe versucht, das Hinzufügen einer @JsonSerialize Annotation die Eigenschaft, so:

@JsonSerialize(using = ToStringSerializer.class) 
private com.google.common.base.Optional<Integer> age; 

Aber dann schlägt der Test fehl wie folgt aus:

java.lang.AssertionError: expected [{"age":"1"}] but found [{"age":"Optional.of(1)"}]

Ich habe in com.fasterxml.jackson.datatype.guava.ser.GuavaOptionalSerializer um gesucht, aber ich kann nicht scheinen, um herauszufinden, wie man es richtig verwenden, wenn selbst wenn es sein soll ist auf diese Weise benutzt.

Was kann ich tun, damit dieser Test funktioniert?

P.S. Wenn es nach mir ginge, würde ich das Optional komplett entfernen, aber das ist keine Option.

+0

Ich glaube, Sie auf dem richtigen Weg sind mit 'GuavaOptionalSerializer', aber ich don‘ Ich weiß, wie man es mit der Annotation richtig einstellt – njzk2

Antwort

1

landete ich meine eigenen einfachen Serializer erstellen:

public class OptionalStringSerializer extends JsonSerializer<Optional<Object>> { 
    @Override 
    public void serialize(Optional<Object> value, JsonGenerator gen, 
      SerializerProvider serializers) throws IOException { 
     gen.writeString(value.isPresent() ? value.get().toString() : null); 
    } 
} 

Dies ist, wie ich es angegeben:

@JsonSerialize(using = OptionalStringSerializer.class) 
private com.google.common.base.Optional<Integer> age; 
+1

Eine Alternative, da es für meine Augen seltsam erscheint, ein ternary auf einem Optional zu verwenden: writeString (value.map (Object :: toString). orElse (null)) –

+0

Die 'Karte () 'Methode ist in Guava nicht verfügbar. – mattalxndr

+0

Ah, hatte im Kopf JDKs optional ... Ich denke, Sie könnten das gleiche Ergebnis erreichen mit 'Optional # transform' und' Optional.oderNull'. –