Ubah nama properti gaya JSON menjadi nama Java CamelCase dengan GSON

107

Saya menggunakan GSON untuk mengonversi data JSON yang saya dapatkan ke objek Java. Ini bekerja dengan cukup baik di semua pengujian saya. Masalahnya adalah objek nyata kita memiliki beberapa properti bernama seperti is_online. GSON hanya memetakannya jika namanya benar-benar sama, alangkah baiknya jika GSON mengonversi nama tersebut menjadi kasus unta Java isOnline.

Tampaknya hal ini dimungkinkan saat membuat data JSON, huruf besar / kecil diubah menjadi garis bawahi kata-kata yang dipisahkan di JSON. Tetapi saya tidak dapat menemukan cara untuk menentukan ini dengan cara lain.

Janusz
sumber
5
Saya akan mengusulkan untuk menerima jawaban
JeanValjean

Jawaban:

313

Saya telah menemukan pengaturan berikut berfungsi sempurna saat membaca json dengan atribut yang digarisbawahi dan menggunakan camelcasing dalam model saya.

Gson gson = new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
    .create()
Hampei
sumber
2
Jawaban yang bagus, terima kasih! @janusz, jika ada dari jawaban ini yang membantu Anda, tandai sebagai Jawaban yang Diterima.
sufinawaz
1
Jika Anda memiliki kasus di mana nama tersebut berisi dua garis bawah, itu mengabaikan garis bawah pertama. Ex. this_key_has__two_underscores akan diubah menjadi thisKeyHas_TwoUnderscores dan begitu juga sebaliknya. Titik kuncinya adalah FieldNamingPolicy di mana enum mengatakan "huruf kecil" dengan garis bawah sementara di sini nama yang diubah memiliki huruf besar dengan garis bawah (_T).
Deepak GM
Sangat sederhana, menyelamatkan saya dari keharusan memberi keterangan pada banyak bidang!
William T. Mallard
99

Anda dapat menggunakan SerializedNameanotasi:

@SerializedName("field_name_in_json")
private final String fieldNameInJava;

Catatan: Bila Anda sudah menyetel FieldNamingPolicy, SerializedNameakan menimpa pengaturannya untuk bidang tertentu (cukup berguna untuk kasus khusus).

saschoar
sumber
2

Ingatlah bahwa contoh Anda adalah case edge. Jika Anda memiliki properti 'foo' getternya harus dinamai 'getFoo', dan jika Anda memiliki properti bernama 'foo_bar' getternya harus dinamai 'getFooBar', namun, dalam contoh Anda, Anda memetakan boolean dan boolean memiliki konvensi penamaan kasus khusus di java. Properti boolean primitif bernama online harus memiliki getter bernama 'isOnline', BUKAN 'getOnline' atau bahkan lebih buruk lagi, 'getIsOnline'. Objek pembungkus boolean (yaitu Boolean) tidak boleh mengikuti kasus khusus ini dan properti bernama 'online' harus memiliki getter bernama 'getOnline'.

Oleh karena itu, memiliki properti boolean dengan 'ada' di namanya adalah kasus tepi, di mana Anda ingin menghapus awalan khusus ini selama konversi Anda. Di arah sebaliknya, kode Anda mungkin ingin memeriksa objek json untuk nama properti mentah serta versi 'is_XXX'.

Jherico
sumber
2

Saya pikir apa yang Anda inginkan ada di sini . Dengan menggunakan anotasi, Anda dapat memberi tahu GSON bahwa mySuperCoolField sebenarnya disebut this_field_is_fun di JSON dan akan membukanya dengan benar. Setidaknya saya pikir ini juga berfungsi untuk deserialization.

Jika tidak berhasil, Anda dapat menggunakan JsonSerializer / JsonDeserializers kustom, yang berfungsi dengan baik, tetapi Anda harus memperbaruinya untuk perubahan di kelas Anda (seperti saat Anda menambahkan kolom). Anda kehilangan keajaiban otomatis.

Hal termudah untuk dilakukan (yang akan jelek, tetapi sangat bersih dan sederhana jika saran pertama tidak berhasil) adalah dengan memberi nama bidang dengan cara membuat GSON senang, dan menambahkan metode pengakses tambahan dengan nama yang Anda suka , mis

public boolean isXXX() {return this.is_XXX;}
MBCook
sumber
hal yang mudah adalah apa yang saya lakukan saat ini dan bekerja dengan baik. Semua kode bergaya java yang tidak biasa disembunyikan di kelas data dan tidak ada orang dari luar yang akan melihatnya. Tapi itu masih sedikit mengganggu saya :)
Janusz