Jackson ignoriert Eigenschaften beim Marshalling

1. Übersicht

Dieses Tutorial zeigt, wie Sie bestimmte Felder ignorieren, wenn Sie ein Objekt mit Jackson 2.x in JSON serialisieren .

Dies ist sehr nützlich, wenn die Jackson-Standardeinstellungen nicht ausreichen und wir genau steuern müssen, was in JSON serialisiert wird - und es gibt verschiedene Möglichkeiten, Eigenschaften zu ignorieren.

Wenn Sie tiefer graben und andere coole Dinge lernen möchten, die Sie mit dem Jackson tun können, besuchen Sie das Haupt-Tutorial von Jackson.

2. Felder auf Klassenebene ignorieren

Wir können bestimmte Felder auf Klassenebene ignorieren, indem wir die Annotation @ JsonIgnoreProperties verwenden und die Felder nach Namen angeben :

@JsonIgnoreProperties(value = { "intValue" }) public class MyDto { private String stringValue; private int intValue; private boolean booleanValue; public MyDto() { super(); } // standard setters and getters are not shown }

Wir können jetzt testen, dass das Feld nach dem Schreiben des Objekts in JSON tatsächlich nicht Teil der Ausgabe ist:

@Test public void givenFieldIsIgnoredByName_whenDtoIsSerialized_thenCorrect() throws JsonParseException, IOException { ObjectMapper mapper = new ObjectMapper(); MyDto dtoObject = new MyDto(); String dtoAsString = mapper.writeValueAsString(dtoObject); assertThat(dtoAsString, not(containsString("intValue"))); }

3. Feld auf Feldebene ignorieren

Wir können ein Feld auch direkt über die Annotation @ JsonIgnore direkt im Feld ignorieren :

public class MyDto { private String stringValue; @JsonIgnore private int intValue; private boolean booleanValue; public MyDto() { super(); } // standard setters and getters are not shown }

Wir können jetzt testen, ob das intValue- Feld tatsächlich nicht Teil der serialisierten JSON-Ausgabe ist:

@Test public void givenFieldIsIgnoredDirectly_whenDtoIsSerialized_thenCorrect() throws JsonParseException, IOException { ObjectMapper mapper = new ObjectMapper(); MyDto dtoObject = new MyDto(); String dtoAsString = mapper.writeValueAsString(dtoObject); assertThat(dtoAsString, not(containsString("intValue"))); }

4. Ignorieren Sie alle Felder nach Typ

Schließlich können wir alle Felder eines angegebenen Typs mithilfe der Annotation @ JsonIgnoreType ignorieren . Wenn wir den Typ steuern, können wir die Klasse direkt mit Anmerkungen versehen:

@JsonIgnoreType public class SomeType { ... }

Meistens haben wir jedoch keine Kontrolle über die Klasse selbst; In diesem Fall können wir Jackson-Mixins gut gebrauchen .

Zuerst definieren wir ein MixIn für den Typ, den wir ignorieren möchten , und kommentieren dies stattdessen mit @JsonIgnoreType :

@JsonIgnoreType public class MyMixInForIgnoreType {}

Dann registrieren wir dieses Mixin, um alle String [] -Typen während des Marshalling zu ersetzen (und zu ignorieren) :

mapper.addMixInAnnotations(String[].class, MyMixInForIgnoreType.class);

Zu diesem Zeitpunkt werden alle String-Arrays ignoriert, anstatt in JSON gemarshallt zu werden:

@Test public final void givenFieldTypeIsIgnored_whenDtoIsSerialized_thenCorrect() throws JsonParseException, IOException { ObjectMapper mapper = new ObjectMapper(); mapper.addMixIn(String[].class, MyMixInForIgnoreType.class); MyDtoWithSpecialField dtoObject = new MyDtoWithSpecialField(); dtoObject.setBooleanValue(true); String dtoAsString = mapper.writeValueAsString(dtoObject); assertThat(dtoAsString, containsString("intValue")); assertThat(dtoAsString, containsString("booleanValue")); assertThat(dtoAsString, not(containsString("stringValue"))); }

und hier ist unser DTO:

public class MyDtoWithSpecialField { private String[] stringValue; private int intValue; private boolean booleanValue; }

Hinweis: Seit Version 2.5 können wir diese Methode anscheinend nicht zum Ignorieren primitiver Datentypen verwenden, sondern für benutzerdefinierte Datentypen und Arrays.

5. Felder mit Filtern ignorieren

Schließlich können wir auch Filter verwenden, um bestimmte Felder in Jackson zu ignorieren . Zuerst müssen wir den Filter für das Java-Objekt definieren:

@JsonFilter("myFilter") public class MyDtoWithFilter { ... }

Dann definieren wir einen einfachen Filter, der das intValue- Feld ignoriert :

SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter .serializeAllExcept("intValue"); FilterProvider filters = new SimpleFilterProvider() .addFilter("myFilter", theFilter);

Jetzt können wir das Objekt serialisieren und sicherstellen, dass das intValue- Feld in der JSON-Ausgabe nicht vorhanden ist:

@Test public final void givenTypeHasFilterThatIgnoresFieldByName_whenDtoIsSerialized_thenCorrect() throws JsonParseException, IOException { ObjectMapper mapper = new ObjectMapper(); SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter .serializeAllExcept("intValue"); FilterProvider filters = new SimpleFilterProvider() .addFilter("myFilter", theFilter); MyDtoWithFilter dtoObject = new MyDtoWithFilter(); String dtoAsString = mapper.writer(filters).writeValueAsString(dtoObject); assertThat(dtoAsString, not(containsString("intValue"))); assertThat(dtoAsString, containsString("booleanValue")); assertThat(dtoAsString, containsString("stringValue")); System.out.println(dtoAsString); }

6. Fazit

Der Artikel hat gezeigt, wie Felder bei der Serialisierung ignoriert werden - zuerst nach Namen, dann direkt und schließlich - wir haben den gesamten Java-Typ mit MixIns ignoriert und Filter verwendet, um die Ausgabe besser steuern zu können.

Die Implementierung all dieser Beispiele und Codefragmente finden Sie in meinem GitHub-Projekt.