Próbuję nauczyć się Gsona i walczę o wykluczenie z pola. Oto moje zajęcia
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;
}
Mogę użyć GsonBuilder i dodać ExclusionStrategy dla nazwy pola jak firstName
lub, country
ale wydaje mi się, że nie jestem w stanie wykluczyć właściwości niektórych pól takich jak country.name
.
Przy użyciu tej metody public boolean shouldSkipField(FieldAttributes fa)
FieldAttributes nie zawiera wystarczającej ilości informacji, aby dopasować pole do filtru podobnego do country.name
.
PS: Chcę uniknąć adnotacji, ponieważ chcę to poprawić i użyć RegEx do odfiltrowania pól.
Edycja : Próbuję sprawdzić, czy można emulować zachowanie wtyczki Struts2 JSON
za pomocą Gson
<interceptor-ref name="json">
<param name="enableSMD">true</param>
<param name="excludeProperties">
login.password,
studentList.*\.sin
</param>
</interceptor-ref>
Edycja: Ponownie otworzyłem pytanie z następującym dodatkiem:
Dodałem drugie pole tego samego typu, aby później wyjaśnić ten problem. Zasadniczo chcę wykluczyć, country.name
ale nie countrOfBirth.name
. Nie chcę również wykluczać kraju jako typu. Więc typy są takie same, to faktyczne miejsce na wykresie obiektowym, które chcę wskazać i wykluczyć.
źródło
JsonSerializer
dla jakiegoś typu -Country
w twoim przypadku - dla którego następnie jest stosowany iExclusionStrategy
który decyduje, które pola serializować.Odpowiedzi:
Wszelkie pola, których generalnie nie chcesz serializować, powinieneś użyć modyfikatora „przejściowego”, a dotyczy to także serializatorów json (przynajmniej dotyczy kilku, których użyłem, w tym gson).
Jeśli nie chcesz, aby nazwa pojawiała się w serializowanym pliku Json, podaj mu przejściowe słowo kluczowe, np .:
Więcej szczegółów w dokumentacji Gson
źródło
transient
zamiast tego@Expose
polega na tym, że nadal musisz wykpić POJO na swoim kliencie ze wszystkimi polami, które mogą się pojawić. W przypadku interfejsu API zaplecza, który może być współdzielony między projektami, może to być problematyczne w przypadku dodatkowe pola są dodawane. Zasadniczo jest to biała lista vs. czarna lista pól.Nishant zapewnił dobre rozwiązanie, ale istnieje prostszy sposób. Po prostu zaznacz wybrane pola adnotacją @Expose, na przykład:
Pomiń wszystkie pola, których nie chcesz serializować. Następnie po prostu utwórz obiekt Gson w ten sposób:
źródło
Więc chcesz wykluczyć
firstName
icountry.name
. Oto jakExclusionStrategy
powinieneś wyglądaćJeśli przyjrzysz się uważnie, wróci
true
doStudent.firstName
iCountry.name
, co chcesz wykluczyć.Musisz zastosować to w
ExclusionStrategy
ten sposób,Zwraca to:
Zakładam, że obiekt wiejski jest inicjowany
id = 91L
w klasie studenckiej.Możesz mieć ochotę. Na przykład nie chcesz serializować żadnego pola zawierającego ciąg „nazwa” w jego nazwie. Zrób to:
Zwróci to:
EDYCJA: Dodano więcej informacji zgodnie z żądaniem.
To
ExclusionStrategy
wystarczy, ale musisz przekazać „W pełni kwalifikowana nazwa pola”. Patrz poniżej:Oto, w jaki sposób możemy go ogólnie użyć.
Zwraca:
źródło
country.name
i wykluczać pole tylkoname
podczas serializacji polacountry
. Powinien być na tyle ogólny, aby dotyczyć każdej klasy, która ma właściwość o nazwie kraj klasy Country. Nie chcę tworzyć strategii wykluczania dla każdej klasyPo przeczytaniu wszystkich dostępnych odpowiedzi odkryłem, że najbardziej elastycznym, w moim przypadku, było użycie niestandardowej
@Exclude
adnotacji. W związku z tym wdrożyłem prostą strategię (nie chciałem oznaczać wszystkich pól za pomocą,@Expose
ani nie chciałem używać,transient
które były w konflikcie przySerializable
serializacji aplikacji ):Adnotacja:
Strategia:
Stosowanie:
źródło
addSerializationExclusionStrategy
lubaddDeserializationExclusionStrategy
zamiastsetExclusionStrategies
f.getAnnotation(Exclude.class) != null
naf.getAnnotation(Exclude.class) == null
transient
powodu potrzeb innych bibliotek. Dzięki!Natknąłem się na ten problem, w którym miałem niewielką liczbę pól, które chciałem wykluczyć tylko z serializacji, więc opracowałem dość proste rozwiązanie, które wykorzystuje
@Expose
adnotację Gsona z niestandardowymi strategiami wykluczania.Jedynym wbudowanym sposobem użycia
@Expose
jest ustawienieGsonBuilder.excludeFieldsWithoutExposeAnnotation()
, ale jak wskazuje nazwa, pola bez wyraźnego tekstu@Expose
są ignorowane. Ponieważ miałem tylko kilka pól, które chciałem wykluczyć, perspektywa dodania adnotacji do każdego pola była bardzo kłopotliwa.Skutecznie chciałem mieć odwrotność, w której wszystko było zawarte, chyba że wyraźnie
@Expose
to wykluczyłem. W tym celu zastosowałem następujące strategie wykluczania:Teraz mogę łatwo wykluczyć kilka pól z
@Expose(serialize = false)
lub@Expose(deserialize = false)
adnotacjami (zwróć uwagę, że domyślną wartością dla obu@Expose
atrybutów jesttrue
). Możesz oczywiście użyć@Expose(serialize = false, deserialize = false)
, ale jest to bardziej zwięzłe, zadeklarując poletransient
zamiast tego (co nadal obowiązuje w przypadku tych niestandardowych strategii wykluczania).źródło
Możesz eksplorować drzewo Json za pomocą gson.
Wypróbuj coś takiego:
Możesz także dodać niektóre właściwości:
Testowane z gson 2.2.4.
źródło
Wymyśliłem fabrykę klas, która wspiera tę funkcjonalność. Przekaż dowolną kombinację pól lub klas, które chcesz wykluczyć.
Aby użyć, utwórz dwie listy (każda jest opcjonalna) i utwórz obiekt GSON:
źródło
Rozwiązałem ten problem za pomocą niestandardowych adnotacji. To jest moja klasa adnotacji „SkipSerialisation”:
i to jest mój GsonBuilder:
Przykład:
źródło
@Retention(RetentionPolicy.RUNTIME)
do swojej adnotacji.Lub może powiedzieć, jakie pola nie zostaną ujawnione za pomocą:
w twojej klasie na atrybucie:
źródło
excludeFieldsWithModifiers()
.Użyłem tej strategii: wykluczyłem wszystkie pola, które nie są oznaczone adnotacją @SerializedName , tj .:
Powraca
źródło
Innym podejściem (szczególnie przydatnym, jeśli trzeba podjąć decyzję o wykluczeniu pola w czasie wykonywania) jest zarejestrowanie TypeAdapter w instancji gson. Przykład poniżej:
W poniższym przypadku serwer oczekiwałby jednej z dwóch wartości, ale ponieważ obie były ints, gson serializował je obie. Moim celem było pominięcie wartości zerowej (lub mniejszej) w pliku Json wysyłanym na serwer.
źródło
@Transient
Adnotacja Kotlina najwyraźniej rozwiązuje ten problem.Wynik:
źródło
Pracuję, umieszczając
@Expose
adnotację, tutaj moja wersja, której używamW
Model
klasie:W
Adapter
klasie:źródło
Mam wersję Kotlin
i jak możesz to dodać do Retrofit GSONConverterFactory:
źródło
Tego zawsze używam:
Domyślnym zachowaniem zaimplementowanym w Gson jest ignorowanie pól obiektów zerowych.
Oznacza, że obiekt Gson nie serializuje pól z zerowymi wartościami do JSON. Jeśli pole w obiekcie Java ma wartość NULL, Gson je wyklucza.
Możesz użyć tej funkcji, aby przekonwertować jakiś obiekt na null lub dobrze ustawiony samodzielnie
źródło