2015-12-15 12 views
11

Ich schreibe einen JSON-Client für einen Server, der Boolean Werte als "0" und "1" zurückgibt. Ich erhalte derzeit die folgende Ausnahme, wenn ich versuche, meine Json Client auszuführen:Wie kann ich einen booleschen Wert aus FasterXML Jackson als Int serialisieren/deserialisieren?

HttpMessageNotReadableException: Could not read JSON: Can not construct instance of java.lang.Boolean from String value '0': only "true" or "false" recognized 

So wie kann ich Setup FasterXML \ Jackson richtig wie etwas zu analysieren:

{ 
    "SomeServerType" : { 
    "ID" : "12345", 
    "ThisIsABoolean" : "0", 
    "ThisIsABooleanToo" : "1" 
    } 
} 

Probe Pojo suchen:

@JsonInclude(JsonInclude.Include.NON_NULL) 
@JsonPropertyOrder({"someServerType"}) 
public class myPojo 
{ 
    @JsonProperty("someServerType") 
    SomeServerType someServerType; 

    @JsonProperty("someServerType") 
    public SomeServerType getSomeServerType() { return someServerType; } 

    @JsonProperty("someServertype") 
    public void setSomeServerType(SomeServerType type) 
    { someServerType = type; } 
} 

@JsonInclude(JsonInclude.Include.NON_NULL) 
@JsonPropertyOrder({"someServerType"}) 
public class SomeServerType 
{ 
    @JsonProperty("ID") 
    Integer ID; 

    @JsonProperty("ThisIsABoolean") 
    Boolean bool; 

    @JsonProperty("ThisIsABooleanToo") 
    Boolean boolToo; 

    @JsonProperty("ID") 
    public Integer getID() { return ID; } 

    @JsonProperty("ID") 
    public void setID(Integer id) 
    { ID = id; } 

    @JsonProperty("ThisIsABoolean") 
    public Boolean getThisIsABoolean() { return bool; } 

    @JsonProperty("ThisIsABoolean") 
    public void setThisIsABoolean(Boolean b) { bool = b; } 

    @JsonProperty("ThisIsABooleanToo") 
    public Boolean getThisIsABooleanToo() { return boolToo; } 

    @JsonProperty("ThisIsABooleanToo") 
    public void setThisIsABooleanToo(Boolean b) { boolToo = b; } 
} 

Rast Client Line
Anmerkung 1: Dies wird Frühling mit 3,2
Anmerkung 2: toJSONString() - ist eine Hilfsmethode, die Jackson verwendet meine Parameter zu serialisiert Objekt
Hinweis 3: die Ausnahme geschieht auf Lesen IN das Ergebnis Objekt

DocInfoResponse result = restTemplate.getForObject(docInfoURI.toString() 
            + "/?input={input}", 
            DocInfoResponse.class, 
            toJSONString(params)); 
+0

Bitte geben Sie den relevanten Code Ihres Kunden an. – Alfabravo

+0

Sie können Getter-Methoden für jene Werte definieren, die etwas zurückgeben wie 'return" 1 ".equals (stringRepresentation);'. – Titus

Antwort

22

Da die Antwort von Paulo Pedroso erwähnt und referenziert wurde, müssen Sie Ihre eigenen benutzerdefinierten Rollen JsonSerializer und rollen. Nach der Erstellung müssen Sie die Anmerkungen @JsonSerialize und @JsonDeserialize Ihrer Immobilie hinzufügen. Spezifizierung der Klasse, die für jede verwendet werden soll.

Ich habe ein kleines (hoffentlich direktes) Beispiel unten zur Verfügung gestellt. Weder die Serializer noch Deserializer-Implementierungen sind super robust, aber dies sollte Ihnen den Anfang machen.

public static class SimplePojo { 

    @JsonProperty 
    @JsonSerialize(using=NumericBooleanSerializer.class) 
    @JsonDeserialize(using=NumericBooleanDeserializer.class) 
    Boolean bool; 
} 

public static class NumericBooleanSerializer extends JsonSerializer<Boolean> { 

    @Override 
    public void serialize(Boolean bool, JsonGenerator generator, SerializerProvider provider) throws IOException, JsonProcessingException { 
     generator.writeString(bool ? "1" : "0"); 
    } 
} 

public static class NumericBooleanDeserializer extends JsonDeserializer<Boolean> { 

    @Override 
    public Boolean deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException { 
     return !"0".equals(parser.getText()); 
    }  
} 

@Test 
public void readAndWrite() throws JsonParseException, JsonMappingException, IOException { 
    ObjectMapper mapper = new ObjectMapper(); 

    // read it 
    SimplePojo sp = mapper.readValue("{\"bool\":\"0\"}", SimplePojo.class); 
    assertThat(sp.bool, is(false)); 

    // write it 
    StringWriter writer = new StringWriter(); 
    mapper.writeValue(writer, sp); 
    assertThat(writer.toString(), is("{\"bool\":\"0\"}")); 
} 
+1

Eigentlich benötigen Sie den Deserializer nicht: Jackson wird 0/1 automatisch zu einer booleschen POJO-Eigenschaft deserialisieren, ohne eine Anmerkung. Und in meinem Fall brauchte ich auch den Serializer nicht, da der Server, den ich anrufe, True/False-Literale für dieses Feld akzeptiert und konvertiert. Ich vergebe sowieso das Kopfgeld. –

+2

@AndrewSpencer Danke, ich schätze die Auszeichnung. :) Um das klarzustellen, scheint Jackson die Eigenschaft automatisch zu deserialisieren, wenn sie als ** Zahl **, aber nicht als ** Zeichenkette ** erscheint. – callmepills

2

Statt benutzerdefinierten Deserializer, können Sie auch einfach eine Setter wie:

public void setThisIsABoolean(String str) { 
    if ("0".equals(str)) { 
    bool = false; 
    } else { 
    bool = true; 
    } 
} 

da Ihre Methode anderen Typ als behaupten können, was Sie intern verwenden.

Und wenn Sie beide und String unterstützen müssen, können Sie angeben, Wert ist ein Object, und überprüfen Sie, was Sie möglicherweise erhalten.

Es sollte sogar möglich sein, verschiedene Typen für Getter-Methode (Boolean) und Setter (String oder Object) zu haben.

Verwandte Themen