2016-11-17 4 views
1

Ich habe ein Problem. Ich habe gerade das Beispiel von jackson json benutzt, um das Builder-Muster zu deserialisieren, aber ich bekomme immer ein leeres json. Ich benutze Jackson-Databind Version 2.8.4 Fehle ich etwas? Also mein Code ist wie folgt:Builder Muster JSON deserialize

Der Wert Klasse

import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 

@JsonDeserialize(builder=ValueBuilder.class) 
public class Value { 
    private final int x, y; 
    protected Value(int x, int y) { 
     this.x = x; 
     this.y = y; 
    } 
} 

Die ValueBuilder Klasse

import com.fasterxml.jackson.annotation.JsonCreator; 

//@JsonPOJOBuilder(buildMethodName = "build", withPrefix = "with") 
public class ValueBuilder { 
    private int x; 
    private int y; 

    // can use @JsonCreator to use non-default ctor, inject values etc 
    public ValueBuilder() { } 

    // if name is "withXxx", works as is: otherwise use @JsonProperty("x") or @JsonSetter("x")! 
public ValueBuilder withX(int x) { 
    this.x = x; 
    return this; // or, construct new instance, return that 
} 
public ValueBuilder withY(int y) { 
    this.y = y; 
    return this; 
} 
@JsonCreator 
public Value build() { 
    return new Value(x, y); 
    } 
} 

Der Startklasse

public class Start { 
    public static void main(String[] args) throws IOException { 
     Value newValue = new ValueBuilder().withX(2).withY(4).build(); 
     ObjectMapper mapper = new ObjectMapper(); 
     String jsonString = mapper.writeValueAsString(newValue); 
     System.out.println(jsonString); 
    } 
} 
+0

Nicht sicher, warum dies downvoted ist ... – Mena

+0

Ein Deserializer würde mit .readValue verwendet werden * Sie rufen .WriteValue *, die einen Serializer benötigen würde. – NateN

Antwort

0

Sie sind nur zugänglich Getter für fehlende x und y in Ihrem Value Klasse - die ObjectMapper erfordert Zugriff auf diese, um zu serialisieren.

Fügen Sie folgendes zu Ihrer Value Klassendefinition:

public int getX() { 
    return x; 
} 
public int getY() { 
    return y; 
} 

keine Notwendigkeit für zusätzliche Anmerkungen in diesem Zusammenhang.

Ihre JSON wird auszudrucken wie:

{"x":2,"y":4} 

Sie auch die Felder machen könnte public das gleiche Ergebnis zu erreichen, aber das wäre die richtige Verkapselung verunreinigen.

+0

Aber der Ansatz des Builder-Musters ist nicht Setter in der Wertklasse zu haben, nicht wahr? Daher hat die jackson lib seit der 2.x Version die Unterstützung für Builder Muster mit der Annotation "@JsonDeserialize (builder = ValueBuilder.class)" oder wenn ich verschiedene "setter" in der Builder Klasse hätte, mit anderen Präfixen als "with "Ich müsste den Builder mit" @JsonPOJOBuilder (buildMethodName = "build", withPrefix = "set") annotieren ". – MultiShinigami30

+0

Es funktioniert jetzt. Beide Wege, serialisieren und deserialisieren. Ich habe Getter in der Value-Klasse hinzugefügt und einige Anmerkungen in der Builder-Klasse gemacht. Mein Anwendungsfall war, einige Attribute zu haben, die optional sind, wie x immer benötigt wird und y optional ist. Daher habe ich hinzugefügt: private @ JsonProperty ("y") int y; und im Builder-Konstruktor: public ValueBuilder (@JsonProperty ("x") int x) {this.x = x; } Und löschte auch die Builder-Setter-Methode für x, weil x jetzt immer beim Erstellen und Conf benötigt wird. für ObjectMapper: mapper.configure (DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); – MultiShinigami30