String als Liste der Strings deserialisieren
Ich habe ein POJO, das die folgenden Attribute enthält
public class Example {
@JsonProperty("inputFoo")
private String foo
@JsonProperty("inputBar")
private String bar
@JsonProperty("inputBaz")
@JsonDeserialize(using = MyDeserializer.class)
private Set<String> baz
}
Der JSON, mit dem ich arbeite, um diese Daten darzustellen, repräsentiert derzeit das baz-Attribut als einzelne Zeichenfolge:
{"inputFoo":"a", "inputBar":"b", "inputBaz":"c"}
Ich verwende den Jackson ObjectMapper, um zu versuchen, den JSON in mein POJO zu konvertieren. Ich weiß, dass der Eingabe-Baz-String aus dem JSON dem Set, als das ich ihn darstellen möchte, nicht sauber zugeordnet werden kann. Daher habe ich einen benutzerdefinierten Deserializer definiert:
public class MyDeserializer extends StdDeserializer<Set<String>> {
public MyDeserializer(){}
public MyDeserializer(Class<?> vc) {
super(vc);
}
public Set<String> deserialize(JsonParser p, DeserializationContext cxt) throws IOException, JsonProcessingException {
String input = p.readValueAs(String.class);
Set<String> output = new HashSet<>();
if(input != null) {
output.add(input);
}
return output;
}
}
Ich erhalte eine IllegalArgumentException, die auf das Attribut "inputBaz" verweist, zu dem ich Details bereitstellen kann. Hat jemand ein offensichtliches Problem mit meiner Deserializer-Implementierung gesehen? Vielen Dank
Antworten
Sie müssen keinen benutzerdefinierten Deserialisierer implementieren. Verwenden Sie die Funktion ACCEPT_SINGLE_VALUE_AS_ARRAY . Es funktioniert auch für Sets:
Funktion, die bestimmt, ob es akzeptabel ist, Nicht-Array-Werte (in JSON) für die Arbeit mit Java-Auflistungstypen (Arrays, java.util.Collection) zu erzwingen . Wenn diese Option aktiviert ist, versuchen Sammlungsdeserialisierer, Nicht-Array-Werte so zu behandeln, als hätten sie das JSON-Array "implizit" umgeben. Diese Funktion soll aus Kompatibilitäts- / Interoperabilitätsgründen verwendet werden, um mit Paketen (z. B. XML-zu-JSON-Konvertern) zu arbeiten, die das JSON-Array auslassen, wenn nur ein einziges Element im Array vorhanden ist. Die Funktion ist standardmäßig deaktiviert.
Siehe auch:
- com.fasterxml.jackson.databind.exc.MismatchedInputException: Instanz von java.util.ArrayListout of START_OBJECT-Token kann nicht deserialisiert werden
Ersetzen Sie die 2 Konstruktoren durch diesen Konstruktor ohne Argumente:
public MyDeserializer() {
super(TypeFactory.defaultInstance().constructCollectionType(Set.class, String.class));
}
ACCEPT_SINGLE_VALUE_AS_ARRAY wie vorgeschlagen ist eine gute Option.
Vielleicht ist Ihr eigentliches Problem komplizierter, aber wenn nicht, können Sie es auch @JsonCreatoranstelle eines benutzerdefinierten Deserialisierers versuchen . Mögen:
public class Example {
@JsonCreator
public Example(@JsonProperty("inputFoo") String foo,
@JsonProperty("inputBar") String bar,
@JsonProperty("inputBaz") String strBaz) {
this.foo = foo;
this.bar = bar;
this.baz = new HashSet<>();
baz.add(strBaz);
}
private String foo;
private String bar;
private Set<String> baz;
}
Nur um zu zeigen, dass Sie im Allgemeinen die Implementierung eines benutzerdefinierten Deserializers mit vermeiden können, @JsonCreatoraber dennoch einige einfache Konvertierungen vornehmen.