Ich versuche Gson zu lernen und habe Probleme mit dem Ausschluss von Feldern. Hier sind meine Klassen
public class Student {
private Long id;
private String firstName = "Philip";
private String middleName = "J.";
private String initials = "P.F";
private String lastName = "Fry";
private Country country;
private Country countryOfBirth;
}
public class Country {
private Long id;
private String name;
private Object other;
}
Ich kann den GsonBuilder verwenden und eine ExclusionStrategy für einen Feldnamen wie firstName
oder hinzufügen, country
aber ich kann es scheinbar nicht schaffen, Eigenschaften bestimmter Felder wie auszuschließen country.name
.
Mit der Methode enthält public boolean shouldSkipField(FieldAttributes fa)
FieldAttributes nicht genügend Informationen, um das Feld mit einem Filter wie abzugleichen country.name
.
PS: Ich möchte Anmerkungen vermeiden, da ich dies verbessern und RegEx zum Herausfiltern von Feldern verwenden möchte.
Bearbeiten : Ich versuche zu sehen, ob es möglich ist, das Verhalten des Struts2 JSON-Plugins zu emulieren
mit Gson
<interceptor-ref name="json">
<param name="enableSMD">true</param>
<param name="excludeProperties">
login.password,
studentList.*\.sin
</param>
</interceptor-ref>
Bearbeiten: Ich habe die Frage mit folgendem Zusatz erneut geöffnet:
Ich habe ein zweites Feld mit demselben Typ hinzugefügt, um dieses Problem weiter zu klären. Grundsätzlich möchte ich country.name
aber nicht ausschließen countrOfBirth.name
. Ich möchte auch Country nicht als Typ ausschließen. Die Typen sind also die gleichen, es ist die tatsächliche Stelle im Objektdiagramm, die ich lokalisieren und ausschließen möchte.
quelle
JsonSerializer
Typs für einen bestimmten Typ -Country
in Ihrem Fall -, der dann angewendet wird undExclusionStrategy
der entscheidet, welche Felder serialisiert werden sollen.Antworten:
Für alle Felder, die Sie im Allgemeinen nicht serialisieren möchten, sollten Sie den Modifikator "transient" verwenden. Dies gilt auch für json-Serialisierer (zumindest für einige, die ich verwendet habe, einschließlich gson).
Wenn Sie nicht möchten, dass der Name im serialisierten JSON angezeigt wird, geben Sie ihm ein vorübergehendes Schlüsselwort, z.
Weitere Details in der Gson-Dokumentation
quelle
transient
anstelle von@Expose
besteht darin, dass Sie immer noch ein POJO auf Ihrem Client mit allen Feldern verspotten müssen, die möglicherweise eingehen könnten. Im Fall einer Back-End-API, die möglicherweise von Projekten gemeinsam genutzt wird, kann dies problematisch sein zusätzliche Felder werden hinzugefügt. Im Wesentlichen handelt es sich um Whitelisting oder Blacklisting der Felder.Nishant bot eine gute Lösung, aber es gibt einen einfacheren Weg. Markieren Sie einfach die gewünschten Felder mit der Annotation @Expose, z.
Lassen Sie alle Felder weg, die Sie nicht serialisieren möchten. Erstellen Sie dann einfach Ihr Gson-Objekt folgendermaßen:
quelle
Also, wollen Sie ausschließen
firstName
undcountry.name
. SoExclusionStrategy
solltest du aussehenWenn Sie genau sehen, kehrt es
true
fürStudent.firstName
und zurückCountry.name
, was Sie ausschließen möchten.Sie müssen dies
ExclusionStrategy
so anwenden ,Dies gibt zurück:
Ich gehe davon aus, dass das Länderobjekt
id = 91L
in der Schülerklasse initialisiert wird .Sie können Phantasie bekommen. Beispielsweise möchten Sie kein Feld serialisieren, dessen Name die Zeichenfolge "name" enthält. Mach das:
Dies wird zurückkehren:
BEARBEITEN: Weitere Informationen wie gewünscht hinzugefügt.
Dies
ExclusionStrategy
wird die Sache tun, aber Sie müssen "Vollqualifizierter Feldname" übergeben. Siehe unten:Hier ist, wie wir es generisch verwenden können.
Es gibt zurück:
quelle
country.name
folgt und das Feld nurname
beim Serialisieren des Felds ausschließtcountry
. Es sollte allgemein genug sein, um auf jede Klasse angewendet zu werden, die eine Eigenschaft mit dem Namen country of the Country class hat. Ich möchte nicht für jede Klasse eine ExclusionStrategy erstellenNachdem ich alle verfügbaren Antworten gelesen hatte, stellte ich fest, dass es in meinem Fall am flexibelsten war, benutzerdefinierte
@Exclude
Anmerkungen zu verwenden. Also habe ich eine einfache Strategie dafür implementiert (ich wollte nicht alle Felder mit markieren@Expose
oder verwenden,transient
die in Konflikt mit der App-Serializable
Serialisierung stehen):Anmerkung:
Strategie:
Verwendungszweck:
quelle
addSerializationExclusionStrategy
oderaddDeserializationExclusionStrategy
anstelle vonsetExclusionStrategies
f.getAnnotation(Exclude.class) != null
zuf.getAnnotation(Exclude.class) == null
transient
aufgrund der Anforderungen anderer Bibliotheken nicht verwenden können . Vielen Dank!Ich bin auf dieses Problem gestoßen, bei dem ich eine kleine Anzahl von Feldern hatte, die ich nur von der Serialisierung ausschließen wollte. Deshalb habe ich eine ziemlich einfache Lösung entwickelt, die Gsons
@Expose
Annotation mit benutzerdefinierten Ausschlussstrategien verwendet.Die einzige integrierte Möglichkeit besteht darin , Felder ohne explizite
@Expose
Einstellung festzulegenGsonBuilder.excludeFieldsWithoutExposeAnnotation()
, aber wie der Name schon sagt@Expose
ignoriert. Da ich nur wenige Felder hatte, die ich ausschließen wollte, fand ich die Aussicht, die Anmerkung zu jedem Feld hinzuzufügen, sehr umständlich.Ich wollte effektiv das Inverse, in dem alles enthalten war, es sei denn, ich habe es ausdrücklich
@Expose
ausgeschlossen. Ich habe die folgenden Ausschlussstrategien verwendet, um dies zu erreichen:Jetzt kann ich einige Felder mit
@Expose(serialize = false)
oder@Expose(deserialize = false)
Anmerkungen einfach ausschließen (beachten Sie, dass der Standardwert für beide@Expose
Attribute isttrue
). Sie können natürlich verwenden@Expose(serialize = false, deserialize = false)
, aber dies wird präziser erreicht, indem Sietransient
stattdessen das Feld deklarieren (was bei diesen benutzerdefinierten Ausschlussstrategien immer noch wirksam ist).quelle
Sie können den Json-Baum mit Gson erkunden.
Versuchen Sie so etwas:
Sie können auch einige Eigenschaften hinzufügen:
Getestet mit gson 2.2.4.
quelle
Ich habe mir eine Klassenfabrik ausgedacht, um diese Funktionalität zu unterstützen. Übergeben Sie eine beliebige Kombination von Feldern oder Klassen, die Sie ausschließen möchten.
Erstellen Sie zur Verwendung zwei Listen (jede ist optional) und erstellen Sie Ihr GSON-Objekt:
quelle
Ich habe dieses Problem mit benutzerdefinierten Anmerkungen gelöst. Dies ist meine Annotationsklasse "SkipSerialisation":
und das ist mein GsonBuilder:
Beispiel:
quelle
@Retention(RetentionPolicy.RUNTIME)
Ihre Anmerkung hinzufügen .Oder kann sagen, was Felder nicht aussetzen mit:
auf Ihrer Klasse auf Attribut:
quelle
excludeFieldsWithModifiers()
.Ich habe diese Strategie angewendet: Ich habe jedes Feld ausgeschlossen, das nicht mit der Annotation @SerializedName gekennzeichnet ist , dh:
Es kehrt zurück
quelle
Ein anderer Ansatz (besonders nützlich, wenn Sie eine Entscheidung zum Ausschließen eines Felds zur Laufzeit treffen müssen) besteht darin, einen TypeAdapter bei Ihrer gson-Instanz zu registrieren. Beispiel unten:
Im folgenden Fall würde der Server einen von zwei Werten erwarten, aber da beide Ints waren, würde gson beide serialisieren. Mein Ziel war es, jeden Wert, der Null (oder weniger) ist, aus dem auf dem Server veröffentlichten JSON wegzulassen.
quelle
Kotlins
@Transient
Anmerkung macht anscheinend auch den Trick.Ausgabe:
quelle
Ich arbeite nur, indem ich die
@Expose
Anmerkung einfüge, hier meine Version, die ich benutzeIn der
Model
Klasse:In der
Adapter
Klasse:quelle
Ich habe Kotlin-Version
und wie Sie dies zu Retrofit GSONConverterFactory hinzufügen können:
quelle
Das was ich immer benutze:
Das in Gson implementierte Standardverhalten ist, dass Nullobjektfelder ignoriert werden.
Bedeutet, dass das Gson-Objekt keine Felder mit Nullwerten für JSON serialisiert. Wenn ein Feld in einem Java-Objekt null ist, schließt Gson es aus.
Mit dieser Funktion können Sie ein Objekt in null konvertieren oder es selbst festlegen
quelle