แปลงชื่อคุณสมบัติสไตล์ JSON เป็นชื่อ Java CamelCase ด้วย GSON


112

ฉันใช้GSONเพื่อแปลงข้อมูล JSON ที่ได้รับไปยังออบเจ็กต์ Java มันใช้ได้ดีในการทดสอบทั้งหมดของฉัน ปัญหาคือวัตถุจริงของเรามีคุณสมบัติบางอย่างที่ชื่อ is_online GSON จะแมปเฉพาะเมื่อมีชื่อเท่ากันโดยสิ้นเชิงมันจะเป็นการดีที่จะให้ GSON แปลงชื่อเป็น Java camel case isOnline

ดูเหมือนว่าจะเป็นไปได้ในขณะที่สร้างข้อมูล JSON กรณีอูฐจะถูกแปลงเป็นคำที่คั่นด้วยขีดล่างใน JSON แต่ฉันหาวิธีระบุสิ่งนี้ในแบบอื่นไม่ได้


5
ฉันขอเสนอให้ยอมรับคำตอบ
JeanValjean

คำตอบ:


317

ฉันพบว่าการตั้งค่าต่อไปนี้ทำงานได้อย่างสมบูรณ์แบบเมื่ออ่าน json ที่มีแอตทริบิวต์ขีดล่างและใช้ camelcasing ในโมเดลของฉัน

Gson gson = new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
    .create()

2
คำตอบที่ดีขอบคุณ! @janusz หากคำตอบเหล่านี้ช่วยคุณได้โปรดทำเครื่องหมายเป็นคำตอบที่ยอมรับ
sufinawaz

1
หากคุณมีกรณีที่ชื่อมีเครื่องหมายขีดล่างสองอันชื่อนั้นจะไม่สนใจขีดล่างแรก เช่น this_key_has__two_underscores จะถูกแปลงเป็น thisKeyHas_TwoUnderscores และในทางกลับกัน ประเด็นสำคัญคือ FieldNamingPolicy ที่ enum ระบุว่า "ตัวพิมพ์เล็ก" พร้อมขีดล่างในขณะที่ชื่อที่แปลงจะมีตัวพิมพ์ใหญ่ที่มีขีดล่าง (_T)
Deepak GM

ง่ายมากช่วยให้ฉันไม่ต้องใส่คำอธิบายประกอบหลายช่อง!
William T. Mallard

100

คุณสามารถใช้SerializedNameคำอธิบายประกอบ:

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

หมายเหตุ: เมื่อคุณตั้งค่าFieldNamingPolicyเรียบร้อยแล้วSerializedNameจะเขียนทับการตั้งค่าสำหรับฟิลด์นั้น ๆ (ค่อนข้างมีประโยชน์สำหรับกรณีพิเศษ)


2

โปรดจำไว้ว่าตัวอย่างของคุณคือกรณีขอบ หากคุณมีคุณสมบัติ 'foo' ควรตั้งชื่อว่า 'getFoo' และหากคุณมีคุณสมบัติชื่อ 'foo_bar' ตัวรับควรตั้งชื่อว่า 'getFooBar' อย่างไรก็ตามในตัวอย่างของคุณคุณกำลังแมปบูลีนและบูลีน หลักการตั้งชื่อกรณีพิเศษใน java คุณสมบัติบูลีนดั้งเดิมที่ตั้งชื่อทางออนไลน์ควรมี getter ชื่อ 'isOnline' ไม่ใช่ 'getOnline' หรือที่แย่กว่านั้นคือ 'getIsOnline' วัตถุบูลีนแรปเปอร์ (เช่นบูลีน) ไม่ควรเป็นไปตามกรณีพิเศษนี้และคุณสมบัติที่ชื่อ 'ออนไลน์' ควรมี getter ชื่อ 'getOnline'

ดังนั้นการมีคุณสมบัติบูลีนที่มี "is" ในชื่อจึงเป็นกรณีขอบซึ่งคุณจะต้องตัดคำนำหน้าเฉพาะนี้ออกในระหว่างการแปลงของคุณ ในทิศทางกลับกันโค้ดของคุณอาจต้องการตรวจสอบวัตถุ json สำหรับทั้งชื่อคุณสมบัติดิบและเวอร์ชัน 'is_XXX'


2

ผมคิดว่าสิ่งที่คุณต้องการคือที่นี่ การใช้คำอธิบายประกอบช่วยให้คุณสามารถบอก GSON ได้ว่า mySuperCoolField เรียกว่า this_field_is_fun ใน JSON และจะแตกออกอย่างถูกต้อง อย่างน้อยฉันคิดว่ามันใช้ได้กับ deserialization ด้วย

หากไม่ได้ผลคุณสามารถใช้ JsonSerializer / JsonDeserializers แบบกำหนดเองซึ่งใช้งานได้ดี แต่คุณต้องอัปเดตเพื่อการเปลี่ยนแปลงในชั้นเรียนของคุณ (เช่นเมื่อคุณเพิ่มฟิลด์) คุณสูญเสียเวทมนตร์อัตโนมัติ

สิ่งที่ง่ายที่สุดในการทำ (ซึ่งจะดูน่าเกลียด แต่ก็เรียบง่ายมากหากคำแนะนำแรกใช้ไม่ได้ผล) คือเพียงแค่ตั้งชื่อฟิลด์เพื่อให้ GSON มีความสุขและเพิ่มวิธีการเข้าถึงพิเศษด้วยชื่อที่คุณชอบ , เช่น

public boolean isXXX() {return this.is_XXX;}

สิ่งที่ง่ายคือสิ่งที่ฉันกำลังทำอยู่ในขณะนี้และมันก็ใช้ได้ดี โค้ดสไตล์จาวาที่ไม่น่าเกลียดทั่วไปทั้งหมดถูกซ่อนอยู่ในคลาสข้อมูลและไม่มีใครเห็นจากภายนอก แต่ก็ยังจู้จี้ฉันอยู่นิดหน่อย :)
Janusz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.