Ini mungkin duplikat. Tetapi saya tidak dapat menemukan solusi untuk Masalah saya.
saya ada kelas
public class MyResponse implements Serializable {
private boolean isSuccess;
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
}
Getters dan setter dihasilkan oleh Eclipse.
Di kelas lain, saya menyetel nilainya menjadi true, dan menulisnya sebagai string JSON.
System.out.println(new ObjectMapper().writeValueAsString(myResponse));
Di JSON, kuncinya datang sebagai {"success": true}
.
Saya ingin kunci isSuccess
itu sendiri. Apakah Jackson menggunakan metode penyetel saat serialisasi? Bagaimana cara membuat kunci menjadi nama field itu sendiri?
isSuccess
Anda seperti nama metode Anda harusisIsSuccess
saya pikirSetSuccess
karena dibuat oleh Eclipse. (Mengikuti standar)Jawaban:
Ini adalah jawaban yang agak terlambat, tetapi mungkin berguna bagi siapa pun yang datang ke halaman ini.
Solusi sederhana untuk mengubah nama yang akan digunakan Jackson saat membuat serial ke JSON adalah dengan menggunakan anotasi @JsonProperty , jadi contoh Anda akan menjadi:
public class MyResponse implements Serializable { private boolean isSuccess; @JsonProperty(value="isSuccess") public boolean isSuccess() { return isSuccess; } public void setSuccess(boolean isSuccess) { this.isSuccess = isSuccess; } }
Ini kemudian akan diserialkan ke JSON sebagai
{"isSuccess":true}
, tetapi memiliki keuntungan karena tidak harus mengubah nama metode pengambil Anda.Perhatikan bahwa dalam kasus ini Anda juga dapat menulis anotasi karena
@JsonProperty("isSuccess")
hanya memiliki satuvalue
elemensumber
Saya baru-baru ini mengalami masalah ini dan inilah yang saya temukan. Jackson akan memeriksa setiap kelas yang Anda berikan untuk getter dan setter, dan menggunakan metode tersebut untuk serialisasi dan deserialization. Selanjutnya, "get", "adalah" dan "set" dalam metode tersebut akan digunakan sebagai kunci untuk kolom JSON ("isValid" untuk getIsValid dan setIsValid).
public class JacksonExample { private boolean isValid = false; public boolean getIsValid() { return isValid; } public void setIsValid(boolean isValid) { this.isValid = isValid; } }
Demikian pula "isSuccess" akan menjadi "sukses", kecuali diganti namanya menjadi "isIsSuccess" atau "getIsSuccess"
Baca lebih lanjut di sini: http://www.citrine.io/blog/2015/5/20/jackson-json-processor
sumber
Menggunakan kedua anotasi di bawah ini, memaksa keluaran JSON untuk menyertakan
is_xxx
:@get:JsonProperty("is_something") @param:JsonProperty("is_something")
sumber
Anda dapat mengonfigurasi Anda
ObjectMapper
sebagai berikut:mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() { @Override public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) { if(method.hasReturnType() && (method.getRawReturnType() == Boolean.class || method.getRawReturnType() == boolean.class) && method.getName().startsWith("is")) { return method.getName(); } return super.nameForGetterMethod(config, method, defaultName); } });
sumber
Saat Anda menggunakan Kotlin dan kelas data:
data class Dto( @get:JsonProperty("isSuccess") val isSuccess: Boolean )
Anda mungkin perlu menambahkan
@param:JsonProperty("isSuccess")
jika Anda juga akan melakukan deserialisasi JSON.sumber
Membangun di atas jawaban Utkarsh ..
Nama pengambil dikurangi get / digunakan sebagai nama JSON.
public class Example{ private String radcliffe; public getHarryPotter(){ return radcliffe; } }
disimpan sebagai {"harryPotter": "everythingYouGaveHere"}
Untuk Deserialization, Jackson memeriksa penyetel dan nama field. Untuk Json String {"word1": "example"} , kedua hal di bawah ini valid.
public class Example{ private String word1; public setword2( String pqr){ this.word1 = pqr; } } public class Example2{ private String word2; public setWord1(String pqr){ this.word2 = pqr ; } }
Pertanyaan yang lebih menarik adalah urutan mana yang dipertimbangkan Jackson untuk deserialisasi. Jika saya mencoba untuk menghilangkan nama {"word1": "myName"} dengan
public class Example3{ private String word1; private String word2; public setWord1( String parameter){ this.word2 = parameter ; } }
Saya tidak menguji kasus di atas, tetapi akan menarik untuk melihat nilai dari kata1 & kata2 ...
Catatan: Saya menggunakan nama yang sangat berbeda untuk menekankan bidang mana yang harus sama.
sumber
ada metode lain untuk masalah ini.
cukup definisikan sub-kelas baru extends PropertyNamingStrategy dan berikan ke instance ObjectMapper.
Berikut ini adalah potongan kode yang bisa membantu lebih banyak:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() { @Override public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) { String input = defaultName; if(method.getName().startsWith("is")){ input = method.getName(); } //copy from LowerCaseWithUnderscoresStrategy if (input == null) return input; // garbage in, garbage out int length = input.length(); StringBuilder result = new StringBuilder(length * 2); int resultLength = 0; boolean wasPrevTranslated = false; for (int i = 0; i < length; i++) { char c = input.charAt(i); if (i > 0 || c != '_') // skip first starting underscore { if (Character.isUpperCase(c)) { if (!wasPrevTranslated && resultLength > 0 && result.charAt(resultLength - 1) != '_') { result.append('_'); resultLength++; } c = Character.toLowerCase(c); wasPrevTranslated = true; } else { wasPrevTranslated = false; } result.append(c); resultLength++; } } return resultLength > 0 ? result.toString() : input; } });
sumber
Saya tidak ingin mengacaukan beberapa strategi penamaan khusus, atau membuat ulang beberapa pengakses.
Semakin sedikit kode, semakin bahagia saya.
Ini melakukan trik untuk kami:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; @JsonIgnoreProperties({"success", "deleted"}) // <- Prevents serialization duplicates public class MyResponse { private String id; private @JsonProperty("isSuccess") boolean isSuccess; // <- Forces field name private @JsonProperty("isDeleted") boolean isDeleted; }
sumber
Jawaban yang diterima tidak akan berhasil untuk kasus saya.
Dalam kasus saya, kelas tersebut bukan milik saya. Kelas bermasalah berasal dari dependensi pihak ke-3, jadi saya tidak bisa hanya menambahkan
@JsonProperty
anotasi di dalamnya.Untuk mengatasinya, terinspirasi dari jawaban @burak di atas, saya membuat custom
PropertyNamingStrategy
sebagai berikut:mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() { @Override public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) { if (method.getParameterCount() == 1 && (method.getRawParameterType(0) == Boolean.class || method.getRawParameterType(0) == boolean.class) && method.getName().startsWith("set")) { Class<?> containingClass = method.getDeclaringClass(); String potentialFieldName = "is" + method.getName().substring(3); try { containingClass.getDeclaredField(potentialFieldName); return potentialFieldName; } catch (NoSuchFieldException e) { // do nothing and fall through } } return super.nameForSetterMethod(config, method, defaultName); } @Override public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) { if(method.hasReturnType() && (method.getRawReturnType() == Boolean.class || method.getRawReturnType() == boolean.class) && method.getName().startsWith("is")) { Class<?> containingClass = method.getDeclaringClass(); String potentialFieldName = method.getName(); try { containingClass.getDeclaredField(potentialFieldName); return potentialFieldName; } catch (NoSuchFieldException e) { // do nothing and fall through } } return super.nameForGetterMethod(config, method, defaultName); } });
Pada dasarnya apa yang dilakukan ini adalah, sebelum membuat serial dan deserialisasi, ia memeriksa di kelas target / sumber nama properti mana yang ada di kelas, apakah itu
isEnabled
atauenabled
properti.Berdasarkan itu, mapper akan membuat serialisasi dan deserialisasi ke nama properti yang ada.
sumber
Anda dapat mengubah boolean primitif menjadi java.lang.Boolean (+ penggunaan
@JsonPropery
)@JsonProperty("isA") private Boolean isA = false; public Boolean getA() { return this.isA; } public void setA(Boolean a) { this.isA = a; }
Bekerja dengan sangat baik untuk saya.
sumber