Saya mencoba belajar Gson dan saya berjuang dengan pengecualian lapangan. Ini kelas saya
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;
}
Saya dapat menggunakan GsonBuilder dan menambahkan ExclusionStrategy untuk nama bidang seperti firstName
atau country
tetapi saya tidak bisa mengatur untuk mengecualikan properti dari bidang tertentu seperti country.name
.
Menggunakan metode ini public boolean shouldSkipField(FieldAttributes fa)
, FieldAttributes tidak mengandung informasi yang cukup untuk mencocokkan bidang dengan filter seperti country.name
.
PS: Saya ingin menghindari anotasi karena saya ingin memperbaiki ini dan menggunakan RegEx untuk menyaring bidang.
Sunting : Saya mencoba melihat apakah mungkin untuk meniru perilaku plugin Struts2 JSON
menggunakan Gson
<interceptor-ref name="json">
<param name="enableSMD">true</param>
<param name="excludeProperties">
login.password,
studentList.*\.sin
</param>
</interceptor-ref>
Sunting: Saya membuka kembali pertanyaan dengan tambahan berikut:
Saya menambahkan bidang kedua dengan tipe yang sama untuk lebih memperjelas masalah ini. Pada dasarnya saya ingin mengecualikan country.name
tetapi tidak countrOfBirth.name
. Saya juga tidak ingin mengecualikan Negara sebagai tipe. Jadi jenisnya sama, itu adalah tempat aktual di objek grafik yang ingin saya tunjuk dan kecualikan.
sumber
JsonSerializer
untuk beberapa jenis -Country
dalam kasus Anda - yang kemudian diterapkanExclusionStrategy
yang memutuskan bidang apa untuk diserialisasi.Jawaban:
Setiap bidang yang tidak Anda inginkan serialisasi secara umum Anda harus menggunakan pengubah "transient", dan ini juga berlaku untuk json serializers (setidaknya itu berlaku untuk beberapa yang telah saya gunakan, termasuk gson).
Jika Anda tidak ingin nama muncul di serial json, berikan kata kunci sementara, misalnya:
Lebih detail dalam dokumentasi Gson
sumber
transient
alih-alih@Expose
adalah bahwa Anda masih harus mengejek POJO pada klien Anda dengan semua bidang yang mungkin bisa masuk. Dalam kasus API back-end yang mungkin dibagikan di antara proyek, ini bisa bermasalah jika bidang tambahan ditambahkan. Pada dasarnya itu adalah daftar putih vs daftar hitam bidang.Nishant memberikan solusi yang baik, tetapi ada cara yang lebih mudah. Cukup tandai bidang yang diinginkan dengan anotasi @Ekspose, seperti:
Tinggalkan bidang apa pun yang tidak ingin Anda serialkan. Kemudian buat saja objek Gson Anda dengan cara ini:
sumber
Jadi, Anda ingin mengecualikan
firstName
dancountry.name
. Di sini AndaExclusionStrategy
akan terlihat seperti apaJika Anda melihat dengan seksama itu mengembalikan
true
untukStudent.firstName
danCountry.name
, yang ingin Anda kecualikan.Anda perlu menerapkan ini
ExclusionStrategy
seperti ini,Ini mengembalikan:
Saya berasumsi objek negara diinisialisasi dengan
id = 91L
di kelas siswa.Anda mungkin suka. Misalnya, Anda tidak ingin membuat serial bidang apa pun yang berisi string "nama" dalam namanya. Melakukan hal ini:
Ini akan mengembalikan:
EDIT: Menambahkan lebih banyak informasi seperti yang diminta.
Ini
ExclusionStrategy
akan melakukan hal itu, tetapi Anda harus memberikan "Nama Bidang yang Sepenuhnya Memenuhi Syarat". Lihat di bawah:Inilah cara kita dapat menggunakannya secara umum.
Ia mengembalikan:
sumber
country.name
dan hanya mengecualikan bidangname
saat membuat serial bidangcountry
. Itu harus cukup umum untuk diterapkan pada setiap kelas yang memiliki properti bernama negara dari kelas Country. Saya tidak ingin membuat Strategi Pengecualian untuk setiap kelasSetelah membaca semua jawaban yang tersedia saya temukan, yang paling fleksibel, dalam kasus saya, adalah menggunakan
@Exclude
anotasi khusus . Jadi, saya menerapkan strategi sederhana untuk ini (saya tidak ingin menandai semua bidang menggunakan@Expose
atau saya ingin menggunakantransient
yang bertentangan dengan dalamSerializable
serialisasi aplikasi ):Anotasi:
Strategi:
Pemakaian:
sumber
addSerializationExclusionStrategy
atauaddDeserializationExclusionStrategy
bukannyasetExclusionStrategies
f.getAnnotation(Exclude.class) != null
kef.getAnnotation(Exclude.class) == null
transient
karena kebutuhan perpustakaan lain. Terima kasih!Saya mengalami masalah ini, di mana saya memiliki sejumlah kecil bidang yang ingin saya kecualikan hanya dari serialisasi, jadi saya mengembangkan solusi yang cukup sederhana yang menggunakan
@Expose
anotasi Gson dengan strategi pengecualian kustom.Satu-satunya cara built-in untuk digunakan
@Expose
adalah dengan mengaturGsonBuilder.excludeFieldsWithoutExposeAnnotation()
, tetapi seperti namanya, bidang tanpa eksplisit@Expose
diabaikan. Karena saya hanya memiliki beberapa bidang yang ingin saya kecualikan, saya merasa prospek menambahkan anotasi ke setiap bidang sangat rumit.Saya secara efektif menginginkan kebalikannya, di mana semuanya dimasukkan kecuali saya secara eksplisit digunakan
@Expose
untuk mengecualikannya. Saya menggunakan strategi pengecualian berikut untuk mencapai ini:Sekarang saya dapat dengan mudah mengecualikan beberapa bidang dengan
@Expose(serialize = false)
atau@Expose(deserialize = false)
anotasi (perhatikan bahwa nilai default untuk kedua@Expose
atribut adalahtrue
). Anda tentu saja dapat menggunakan@Expose(serialize = false, deserialize = false)
, tetapi itu lebih ringkas dilakukan dengan mendeklarasikan bidangtransient
sebagai gantinya (yang masih berlaku dengan strategi pengecualian khusus ini).sumber
Anda dapat menjelajahi pohon json dengan gson.
Coba sesuatu seperti ini:
Anda juga dapat menambahkan beberapa properti:
Diuji dengan gson 2.2.4.
sumber
Saya datang dengan pabrik kelas untuk mendukung fungsi ini. Lulus kombinasi apa pun dari bidang atau kelas yang ingin Anda kecualikan.
Untuk menggunakan, buat dua daftar (masing-masing adalah opsional), dan buat objek GSON Anda:
sumber
Saya memecahkan masalah ini dengan anotasi khusus. Ini adalah kelas Anotasi "SkipSerialisation" saya:
dan ini GsonBuilder saya:
Contoh:
sumber
@Retention(RetentionPolicy.RUNTIME)
anotasi Anda.Atau dapat mengatakan bidang apa yang tidak akan dibuka dengan:
di kelas Anda pada atribut:
sumber
excludeFieldsWithModifiers()
untuk itu.Saya menggunakan strategi ini: saya mengecualikan setiap bidang yang tidak ditandai dengan penjelasan @SerializedName , yaitu:
Ia kembali
sumber
Pendekatan lain (terutama berguna jika Anda perlu membuat keputusan untuk mengecualikan bidang saat runtime) adalah mendaftarkan TypeAdapter dengan instance gson Anda. Contoh di bawah ini:
Dalam kasus di bawah ini, server akan mengharapkan salah satu dari dua nilai tetapi karena keduanya ints maka gson akan membuat serial keduanya. Tujuan saya adalah untuk menghilangkan nilai apa pun yang nol (atau kurang) dari json yang diposting ke server.
sumber
@Transient
Anotasi Kotlin juga tampaknya berhasil.Keluaran:
sumber
Saya bekerja hanya dengan meletakkan
@Expose
anotasi, di sini versi saya yang saya gunakanDi
Model
kelas:Di
Adapter
kelas:sumber
Saya memiliki versi Kotlin
dan bagaimana Anda dapat menambahkan ini ke Retrofit GSONConverterFactory:
sumber
Inilah yang selalu saya gunakan:
Perilaku default yang diterapkan di Gson adalah bahwa bidang objek nol diabaikan.
Berarti objek Gson tidak membuat serialisasi bidang dengan nilai nol ke JSON. Jika bidang dalam objek Java adalah null, Gson mengecualikannya.
Anda dapat menggunakan fungsi ini untuk mengubah beberapa objek menjadi nol atau diatur dengan baik oleh Anda sendiri
sumber