Mezők kizárása a Gson sorosításából
1. Áttekintés
Ebben a rövid bemutatóban megvizsgáljuk azokat a lehetőségeket, amelyekkel kizárhatjuk a Java osztály egy vagy több mezőjét és annak alosztályait a Gson sorosításból.
2. Kezdeti beállítás
Először határozzuk meg osztályainkat:
@Data @AllArgsConstructor nyilvános osztály MyClass {private long id; privát karakterlánc neve; privát Húr egyéb; privát MySubClass alosztály; } @Data @AllArgsConstructor nyilvános osztály MySubClass {private long id; privát karakterlánc leírása; privát String egyébVerboseInfo; }
A kényelem kedvéért jegyzeteltük őket a Lombok-ra (szintaktikus cukor szerelőknek, betétkészítőknek, kivitelezőknek).
Töltsük be most őket:
MySubClass alosztály = new MySubClass (42L, "a válasz", "A belsõ mezõ nem sorosít") MyClass forrás = új MyClass (1L, "foo", "bar", alosztály);
Célunk a Sajátosztály.más és MySubClass.otherVerboseInfo mezők sorosítása.
A kimenet, amelyet várhatóan kapunk:
{"id": 1, "name": "foo", "subclass": {"id": 42, "description": "a válasz"}}
Java-ban:
String várhatóResult = "{\" id \ ": 1, \" name \ ": \" foo \ ", \" alosztály \ ": {\" id \ ": 42, \" description \ ": \" a válasz \ "}}";
3. Átmeneti módosító
Jelölhetünk egy mezőt a átmeneti módosító:
nyilvános osztály MyClass {private long id; privát karakterlánc neve; privát tranziens String egyéb; privát MySubClass alosztály; } public class MySubClass {private long id; privát karakterlánc leírása; privát tranziens String egyébVerboseInfo; }
A Gson serializer figyelmen kívül hagy minden átmenetinek nyilvánított mezőt:
Karakterlánc jsonString = új Gson (). ToJson (forrás); assertEquals (várható eredmény, jsonString);
Bár ez nagyon gyors, súlyos hátrányokkal is jár: minden szerializációs eszköz figyelembe veszi a tranzienseket, nemcsak Gson.
A Transient a Java módja annak, hogy kizárjuk a sorosítástól, akkor a mi mezőnket is kiszűrjük SorosíthatóSorosítása, valamint minden objektumunkat kezelő könyvtári eszköz vagy keretrendszer által.
Ezenkívül a átmeneti kulcsszó mindig működik mind a szerializáció, mind a deserializáció esetében, ami a felhasználási esettől függően korlátozó lehet.
4. @Expose Megjegyzés
Gson com.google.gson.annotations @Expose az annotáció fordítva működik.
Használhatjuk a sorosítandó mezők deklarálásához, és a többiek figyelmen kívül hagyásához:
nyilvános osztály MyClass {@Expose private long id; @Expose private String név; privát Húr egyéb; @Expose privát MySubClass alosztály; } nyilvános osztály MySubClass {@Expose private long id; @Expose private String leírás; privát String egyébVerboseInfo; }
Ehhez be kell állítanunk a Gson-t egy GsonBuilder-be:
Gson gson = new GsonBuilder () .excludeFieldsWithoutExposeAnnotation () .create (); Karakterlánc jsonString = gson.toJson (forrás); assertEquals (várható eredmény, jsonString);
Ezúttal terepi szinten ellenőrizhetjük, hogy a szűrés történjen-e sorosítás, deserializáció vagy mindkét esetben (alapértelmezett).
Nézzük meg, hogyan lehet megelőzni Sajátosztály.más nem sorosítják, de lehetővé teszik annak feltöltését a JSON deserializációja során:
@Expose (serialize = false, deserialize = true) private String egyéb;
Bár ez a legegyszerűbb módja a Gson által biztosított, és nem érinti a többi könyvtárat, redundanciát jelenthet a kódban. Ha száz mezővel rendelkező osztályunk van, és csak egy mezőt akarunk kizárni, akkor kilencvenkilenc annotációt kell írnunk, ami túlteljes.
5. ExclusionStrategy
Nagyon testreszabható megoldás az a használata com.google.gson.ExclusionStrategy.
Ez lehetővé teszi számunkra, hogy meghatározzunk (külsőleg vagy Anonimous belső osztály segítségével) egy stratégiát, amellyel utasíthatjuk a GsonBuildert arra, hogy a mezőket (és / vagy osztályokat) egyedi feltételekkel sorosítsa-e.
Gson gson = new GsonBuilder () .addSerializationExclusionStrategy (stratégia) .create (); Karakterlánc jsonString = gson.toJson (forrás); assertEquals (várható eredmény, jsonString);
Lássunk néhány példát az intelligens stratégiákra.
5.1. Osztályok és mezők nevével
Természetesen keményen kódolhatunk egy vagy több mező / osztály nevet is:
ExclusionStrategy stratégia = new ExclusionStrategy () {@Orride public boolean shouldSkipField (FieldAttributes field) {if (field.getDeclaringClass () == MyClass.class && field.getName (). Egyenlő ("egyéb")) {return true; } if (field.getDeclaringClass () == MySubClass.class && field.getName (). egyenlő ("otherVerboseInfo")) {return true; } return false; } @Orride public boolean shouldSkipClass (Class clazz) {return false; }};
Ez gyors és egyenesen lényeges, de nem túl újrafelhasználható, és hajlamos a hibákra is, ha átnevezzük az attribútumainkat.
5.2. Üzleti kritériumokkal
Mivel egyszerűen logikai értéket kell adnunk, ezért minden üzleti logikát megvalósíthatunk a módszeren belül.
A következő példában minden, az „egyéb” kezdetű mezőt azonosítunk olyan mezőként, amelyeket nem szabad sorosítani, függetlenül attól az osztálytól, amelyhez tartoznak:
ExclusionStrategy stratégia = new ExclusionStrategy () {@Orride public boolean shouldSkipClass (Class clazz) {return false; } @Orride public boolean shouldSkipField (FieldAttributes field) {return field.getName (). StartsWith ("other"); }};
5.3. Egyéni jelöléssel
Egy másik okos megközelítés egy egyedi kommentár létrehozása:
@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.FIELD) public @interface Kizárás {}
Ezután kihasználhatjuk ExclusionStrategy annak érdekében, hogy pontosan úgy működjön, mint a @Expose kommentár, de fordítva:
nyilvános osztály MyClass {private long id; privát karakterlánc neve; @Kizárja a privát karakterláncot; privát MySubClass alosztály; } public class MySubClass {private long id; privát karakterlánc leírása; @Kizárja a privát karakterláncot egyébVerboseInfo; }
És itt van a stratégia:
ExclusionStrategy stratégia = new ExclusionStrategy () {@Orride public boolean shouldSkipClass (Class clazz) {return false; } @Orride public boolean shouldSkipField (FieldAttributes field) {return field.getAnnotation (Exclude.class)! = Null; }};
Ez a StackOverflow válasz először ezt a technikát írta le.
Ez lehetővé teszi számunkra, hogy egyszer megírjuk az annotációt és a Stratégiát, és további módosítások nélkül dinamikusan jegyezzük fel a mezőinket.
5.4. A kizárási stratégia kiterjesztése a deserializációra
Nem számít, melyik stratégiát fogjuk használni, mindig ellenőrizhetjük, hol kell alkalmazni.
Csak a sorozatosítás során:
Gson gson = new GsonBuilder (). AddSerializationExclusionStrategy (stratégia)
Csak deserializáció során:
Gson gson = new GsonBuilder (). AddDeserializationExclusionStrategy (stratégia)
Mindig:
Gson gson = new GsonBuilder (). SetExclusionStrategies (stratégia);
6. Következtetés
Különböző módszereket láthattunk a mezők kizárására az osztályból és annak alosztályaiból a Gson sorosítása során.
Megvizsgáltuk minden megoldás fő előnyeit és buktatóit is.
Mint mindig, a teljes forráskód elérhető a Githubon.