GSON เป็นไลบรารี Java ที่ใช้ในการใช้การแปลงร่วมกันระหว่างวัตถุ JSON และ Java GSON เป็นโครงการโอเพ่นซอร์สโฮสต์ที่ https://github.com/google/gson
คลาสหลักใน GSON คือ GSON คุณยังสามารถใช้คลาส GSONBUILDER เพื่อตั้งค่าตัวเลือกบางอย่างในขณะที่สร้างวัตถุ GSON
วัตถุ GSON ไม่ได้บันทึกสถานะใด ๆ เมื่อประมวลผล JSON ดังนั้นผู้ใช้จึงสามารถทำการทำให้เป็นอนุกรมการ deserialization และการดำเนินการอื่น ๆ บนวัตถุ GSON เดียวกันได้อย่างง่ายดาย
ตัวอย่าง: การใช้งานพื้นฐาน
// serializationgson gson = new gson (); gson.tojson (1); // ==> พิมพ์ 1gson.tojson ("ABCD"); // ==> พิมพ์ "abcd" gson.tojson (ใหม่ยาว (10)); // ==> พิมพ์ 10int [] ค่า = {1}; gson.tojson (ค่า); // ==> พิมพ์ [1] // deserializationInt one = gson.fromjson ("1", int.class); จำนวนเต็มหนึ่ง = gson.fromjson ("1", integer.class); ยาวหนึ่ง = gson.fromjson ("1" gson.fromjson ("เท็จ", boolean.class); string str = gson.fromjson ("/" abc/"", string.class); string anothertr = gson.fromjson ("[/" abc/"], string.class); gson.tojson (obj); // ==> json คือ {"value1": 1, "value2": "abc"}ตัวอย่าง: การแปลงระหว่างวัตถุและ JSON
กำหนดคลาส bagofprimitives:
BAGOFOFPRIMITIVES คลาส {ค่า INT ส่วนตัว 1 = 1; สตริงส่วนตัวค่า 2 = "ABC"; ค่า int ชั่วคราวส่วนตัว 3 = 3; bagofprimitives () {// no-Args Constructor}}}ต่อเนื่องกับ JSON:
// serializationbagofprimitives obj = ใหม่ bagofprimitives (); gson gson = new gson (); string json = gson.tojson (obj); // ==> json คือ {"value1": 1, "value2": "abc"}อย่าทำให้วัตถุที่เป็นอนุกรมที่มีการอ้างอิงแบบวงกลมมิฉะนั้นการเรียกซ้ำที่ไม่มีที่สิ้นสุดจะเกิดขึ้น
Deserialization:
// deserializationBagofprimitives obj2 = gson.fromjson (json, bagofprimitives.class); // ==> obj2 ก็เหมือนกับ obj
รายละเอียดบางอย่างเมื่อประมวลผลวัตถุ:
การจัดการชั้นเรียนที่ซ้อนกัน (รวมถึงชั้นเรียนภายใน)
GSON สามารถทำให้ชั้นเรียนซ้อนกันได้อย่างง่ายดายและ deserialize คลาสซ้อนกันคงที่ GSON ไม่สามารถ deserialize คลาสภายในที่บริสุทธิ์โดยอัตโนมัติเนื่องจากตัวสร้างพารามิเตอร์ที่ไม่มีพารามิเตอร์ของคลาสด้านในจำเป็นต้องอ้างถึงวัตถุที่มีอยู่ (เช่นอินสแตนซ์ของชั้นนอก) ในการ deserialize คลาสคงที่คุณสามารถคงที่ทั้งคลาสภายในหรือให้ผู้สร้างอินสแตนซ์ที่กำหนดเอง นี่คือตัวอย่าง:
คลาสสาธารณะ A {สตริงสาธารณะ A; คลาส B {สตริงสาธารณะ B; สาธารณะ b () {// ไม่มี args constructor สำหรับ b}}}}คลาส B ข้างต้นไม่สามารถเป็นอนุกรมโดย GSON เนื่องจากคลาส B เป็นคลาสภายใน (ไม่คงที่) GSON จึงไม่สามารถ deserialize {"B": "ABC"} ลงในอินสแตนซ์ของคลาส B หาก B ถูกประกาศว่าเป็นคลาส B BSO
ทางออกอื่นคือการเขียนผู้สร้างอินสแตนซ์สำหรับ B:
คลาสสาธารณะ InstancecreatorBorb ใช้ Instancecreator <ab> {ส่วนตัวสุดท้าย A; Public InstancecreatorBorb (a) {this.a = a; } Public Ab CreateInstance (ประเภทประเภท) {return a.new b (); -วิธีนี้เป็นไปได้ แต่ไม่แนะนำ (นักแปลบอกว่าเขาไม่เข้าใจผู้สร้างอินสแตนซ์นี้และไม่รู้วิธีใช้)
ตัวอย่าง: อาร์เรย์
GSON GSON = new GSON (); int [] ints = {1, 2, 3, 4, 5}; string [] strings = {"abc", "def", "ghi"}; // serializationgson.tojson (ints); ==> พิมพ์ [1,2,3,4,5] gson.tojson (สตริง); ==> prints ["abc", "def", "ghi"] // deserializationint [] ints2 = gson.fromjson ("[1,2,3,4,4,5]", int []. class); ==> ints2GSON ยังรองรับอาร์เรย์หลายมิติที่มีชนิดข้อมูลที่ซับซ้อน
ตัวอย่าง: คอลเลกชัน
GSON GSON = new GSON (); คอลเลกชัน <Integer> ints = lists.immutableList (1,2,3,4,5); // serializationstring json = gson.tojson (ints); // ==> JSON คือ [1,2,3,4,5] // deserializationType collectionType = typetoken ใหม่ <การรวบรวม <จำนวนเต็ม >> () {}. getType (); คอลเลกชัน <teger> ints2 = gson.fromjsonข้อ จำกัด เมื่อประมวลผลคอลเลกชัน:
serialize/deserialize ทั่วไป
เมื่อใช้ TOJSON (OBJ) GSON จะเรียก OBJ.GetClass () เพื่อรับข้อมูลภาคสนามเพื่อใช้ในการทำให้เป็นอนุกรม ในทำนองเดียวกันวัตถุ myclass.class สามารถส่งผ่านเป็นพารามิเตอร์ไปยังวิธีการ FromJSON (JSON, myclass.class) ซึ่งสามารถใช้เมื่อวัตถุไม่ใช่ทั่วไป อย่างไรก็ตามเมื่อวัตถุเป็นวัตถุประเภททั่วไปข้อมูลประเภททั่วไปจะหายไปเนื่องจากกลไกการลบประเภทใน Java ตัวอย่างต่อไปนี้แสดงสิ่งนี้:
คลาส foo <t> {t value;} gson gson = new gson (); foo <bar> foo = new foo <bar> (); gson.tojson (foo); // ไม่สามารถทำให้ foo.value ได้อย่างถูกต้อง reutlygson.fromjson (json, foo.getclass ()); // ล้มเหลวในการ deserialize foo.value เป็นบาร์รหัสข้างต้นจะตีความค่าเป็นประเภทแท่งเนื่องจาก GSON เรียก foo.getClass () เพื่อรับข้อมูลของคลาส แต่วิธีนี้จะส่งคืนคลาสดั้งเดิมคือ foo.class ซึ่งหมายความว่า GSON ไม่สามารถรู้ได้ว่านี่เป็นวัตถุของ Type Foo <bar>
ในการแก้ปัญหานี้คุณสามารถระบุประเภทพารามิเตอร์ที่ถูกต้องสำหรับทั่วไปของคุณ คุณสามารถใช้คลาส Typetoken ที่ต้องทำ:
type footype = typetoken ใหม่ <foo <bar>> () {} .getType (); gson.tojson (foo, footype); gson.fromjson (json, footype);FOOTYPE จริงกำหนดคลาสภายในที่ไม่ระบุชื่อซึ่งมีวิธี getType () ที่สามารถส่งคืนประเภทพารามิเตอร์ทั้งหมด
serialize/deserialize ชุดของวัตถุทุกประเภท
บางครั้ง JSON ที่ผ่านการประมวลผลมีชนิดผสมเช่น:
['สวัสดี', 5, {ชื่อ: 'ทักทาย', แหล่งที่มา: 'แขก'}]ชุดที่เกี่ยวข้องควรเป็น:
คอลเลกชันคอลเลกชัน = new ArrayList (); collect.add ("สวัสดี"); collect.add (5); collect.add (เหตุการณ์ใหม่ ("ทักทาย", "แขก"));คลาสเหตุการณ์ถูกกำหนดดังนี้:
เหตุการณ์ในชั้นเรียน {ชื่อสตริงส่วนตัว; แหล่งสตริงส่วนตัว เหตุการณ์ส่วนตัว (ชื่อสตริง, แหล่งที่มาของสตริง) {this.name = name; this.source = แหล่งที่มา; -ด้วย GSON คุณไม่จำเป็นต้องทำอะไรเป็นพิเศษเพื่อทำให้คอลเลกชันเป็นอนุกรม: TOJSON (คอลเลกชัน) จะส่งออกผลลัพธ์ที่น่าพอใจ
อย่างไรก็ตามการ deserialization ผ่าน FromJSON (JSON, collection.class) เป็นไปไม่ได้เนื่องจาก GSON ไม่สามารถสอดคล้องกับเนื้อหาใน JSON กับประเภท GSON กำหนดให้คุณต้องจัดเตรียมประเภทคอลเลกชันทั่วไปใน FromJSON คุณมีสามตัวเลือก:
โซลูชันที่ 1: ใช้ API ของ GSON Parser (Parser Stream ระดับต่ำหรือ Dom Parser Jsonparser) เพื่อแยกวิเคราะห์องค์ประกอบอาร์เรย์จากนั้นใช้ gson.fromjson () เพื่อประมวลผลแต่ละองค์ประกอบอาร์เรย์ นี่คือโซลูชันที่ต้องการ
โครงการที่ 2: ลงทะเบียนอะแดปเตอร์ประเภทสำหรับคอลเลกชันคลาสไปยังองค์ประกอบแผนที่ในอาร์เรย์ไปยังวัตถุที่เหมาะสม ข้อเสียของวิธีนี้คือมันจะทำให้เกิดความไม่สะดวกเมื่อจัดการกับประเภทคอลเลกชันอื่น ๆ
โครงการที่ 3: ลงทะเบียนอะแดปเตอร์ประเภทสำหรับ MyCollectionMemberType และใช้คอลเลกชัน <MyCollectionMemberType> ใน FRATJSON วิธีนี้เป็นไปได้ก็ต่อเมื่ออาร์เรย์ดูเหมือนองค์ประกอบระดับสูงหรือถ้าคุณสามารถเปลี่ยนประเภทฟิลด์เป็นคอลเลกชัน <mycollectionMemberType>
serializer/deserializer ในตัว
GSON ให้บริการ serializer/deserializer สำหรับคลาสที่ใช้กันทั่วไปซึ่งอาจไม่เหมาะสมสำหรับการเป็นตัวแทนเริ่มต้น
นี่คือรายการของคลาสเหล่านี้:
การทำให้เป็นอนุกรม/deserialization ที่กำหนดเอง
บางครั้งการใช้งานเริ่มต้นของ GSON ไม่ใช่สิ่งที่คุณต้องการซึ่งเป็นเรื่องธรรมดามากขึ้นเมื่อต้องรับมือกับไลบรารีคลาส (เช่น DateTime)
GSON ช่วยให้คุณสามารถลงทะเบียน serializers/deserializers ที่กำหนดเอง ในการทำเช่นนี้คุณต้องใช้ส่วนต่อไปนี้:
JSON Serializer: จำเป็นต้องปรับแต่งอนุกรมสำหรับวัตถุ
JSON DESERIALIZER: คุณต้องปรับแต่งผู้สร้างคลาส Deserialization สำหรับประเภท: หากมีตัวสร้างแบบไม่มีพารามิเตอร์หรือ Deserializer ได้รับการลงทะเบียนแล้วก็ไม่จำเป็น
gsonBuilder gson = new gsonBuilder (); gson.registertypeadapter (mytype2.class, mytypeadapter ใหม่ ()); gson.registertypeadapter (mytype.class, myserializer ใหม่ ()); gson.registertypeadapter myDeserializer ()); gson.registertypeadapter (mytype.class, myinstancecreator ใหม่ ());
RegisterTypeadapter ตรวจสอบว่าอะแดปเตอร์ประเภทใช้งานหลายอินเตอร์เฟสและลงทะเบียนอะแดปเตอร์ประเภทสำหรับอินเทอร์เฟซเหล่านี้หรือไม่
เขียน serializer
นี่คือตัวอย่างของการปรับแต่ง serializer สำหรับ dateTime:
คลาสส่วนตัว DateTimeSerializer ใช้ JSonserializer <TateTime> {Public JSONElement Serialize (DateTime SRC, TypeOfSrc, JonserializationContext บริบท) {ส่งคืน JSONPrimitive ใหม่ (SRC.TOSTRING ()); -GSON เรียก TOJSON () เมื่อมีการทำให้เป็นเซียร์เม้นท์อินสแตนซ์
เขียน deserializer
ตัวอย่างต่อไปนี้แสดงวิธีการเขียน deserializer ของคลาส DateTime:
คลาสส่วนตัว DateTimedEserializer ใช้ JSondeserializer <TateTime> {Public DateTime Deserialize (JSONElement JSON, Type -typeoft, jSondeserialization Context) พ่น jsonparsexception {ส่งคืน dateTime ใหม่ (json.getasjsonprimitive -เมื่อ GSON ต้องการ deserialize สตริง JSON ไปยังวัตถุ DateTime, FromJSON () จะถูกเรียก
สำหรับ serializers/deserializers ควรให้ความสนใจกับ:
เขียนผู้สร้างอินสแตนซ์
เมื่อ deserializing วัตถุ GSON จำเป็นต้องสร้างอินสแตนซ์ของคลาส คลาสที่ทำงานได้ดีในระหว่างการทำให้เป็นอนุกรม/deserialization หมายความว่าคลาสนี้มีตัวสร้างแบบไม่มีพารามิเตอร์ โดยทั่วไปเมื่อจัดการกับคลาสที่ไม่มีตัวสร้างพารามิเตอร์ในไลบรารีคลาสจะต้องมีผู้สร้างอินสแตนซ์
ตัวอย่างผู้สร้างตัวอย่าง:
ชั้นเรียนส่วนตัว MoneyInstancecreator ใช้ Instancecreator <money> {เงินสาธารณะ CreateInstance (ประเภทประเภท) {คืนเงินใหม่ ("10,00000", currencyCode.USD); -ผู้สร้างอินสแตนซ์ประเภทพารามิเตอร์
บางครั้งประเภทที่จะสร้างอินสแตนซ์จะเป็นประเภทพารามิเตอร์ โดยรวมเนื่องจากอินสแตนซ์จริงเป็นประเภทดั้งเดิมนี่ไม่ใช่ปัญหา นี่คือตัวอย่าง:
คลาส mylist <t> ขยาย arraylist <t> {} คลาส mylistinstancecreator ใช้ instancecreator <mylist <? >> {@suppresswarnings ("ไม่ถูกตรวจสอบ") สาธารณะ < คืนใหม่ mylist (); -อย่างไรก็ตามบางครั้งคุณต้องสร้างอินสแตนซ์ตามประเภทพารามิเตอร์จริง ในกรณีนี้คุณสามารถส่งพารามิเตอร์ประเภทไปยังวิธี CreateInstance นี่คือตัวอย่าง:
ID คลาสสาธารณะ <t> {คลาสสุดท้ายของคลาสสุดท้าย <t> classofid; มูลค่าสุดท้ายของเอกชน ID สาธารณะ (คลาส <t> classofid, ค่ายาว) {this.classofid = classofid; this.value = ค่า; }} คลาส idinstancecreator ใช้ instancecreator <id <? >> {id สาธารณะ <?> createInstance (ประเภทประเภท) {ประเภท [] typeParameters = ((parameterizedType) ประเภท) พิมพ์ idType = typeParameters [0]; // id มีเพียงหนึ่งพารามิเตอร์ type t return id.get ((คลาส) idtype, 0l); -ในตัวอย่างข้างต้นอินสแตนซ์ของคลาส ID ไม่สามารถสร้างได้โดยไม่ต้องผ่านประเภทจริงไปยังประเภทพารามิเตอร์ เราสามารถแก้ปัญหานี้ได้โดยผ่านประเภทพารามิเตอร์ไปยังวิธีการ ที่นี่วัตถุประเภทสามารถถือได้ว่าเป็นตัวแทนของประเภทพารามิเตอร์ Java ของ ID <foo> และอินสแตนซ์ที่เกี่ยวข้องควรถูกผูกไว้กับ ID <foo> เนื่องจาก ID คลาสมีพารามิเตอร์หนึ่งพารามิเตอร์หนึ่งพารามิเตอร์เราจึงใช้ GetActualTuthYpeArgument () เพื่อส่งคืนองค์ประกอบที่ 0 ของอาร์เรย์ประเภทในตัวอย่างนี้ foo.class
เอาต์พุตขนาดกะทัดรัดเทียบกับเอาต์พุตที่สวยงาม
ผลลัพธ์เริ่มต้นของ JSON ใน GSON อยู่ในรูปแบบ JSON ขนาดกะทัดรัด กล่าวคือไม่มีตัวละครเว้าพิเศษใน JSON ดังนั้นจึงไม่มีช่องว่างระหว่างชื่อฟิลด์และค่าฟิลด์ระหว่างฟิลด์และระหว่างองค์ประกอบอาร์เรย์ในเอาต์พุตของ JSON นอกจากนี้ฟิลด์ NULL จะไม่ถูกส่งออก (หมายเหตุ: NULL จะถูกเก็บรักษาไว้ในการรวบรวมและอาร์เรย์วัตถุ)
หากคุณต้องการส่งออกได้อย่างสวยงามมากขึ้นคุณต้องใช้ gsonBuilder เพื่อกำหนดค่าอินสแตนซ์ GSON JSONFormatter ไม่มีอยู่ใน API สาธารณะดังนั้นไคลเอนต์ไม่สามารถกำหนดค่าการตั้งค่าเอาต์พุตเริ่มต้นได้ ตอนนี้เราให้เฉพาะ JSONPrintFormatter ซึ่งโดยค่าเริ่มต้นคือ 80 อักขระต่อบรรทัดการเยื้องจะใช้ 2 อักขระและระยะขอบขวาคือ 4 อักขระ
ตัวอย่างต่อไปนี้แสดงวิธีรับอินสแตนซ์ GSON เพื่อใช้ JSONPrintFormatter แทนการใช้ JSONCompactFormatter เริ่มต้น
GSON GSON = new gsonBuilder (). setTrepTyPrinting (). สร้าง (); string jsonOutput = gson.tojson (someObject);
วัตถุเปล่า
ในการใช้งานเริ่มต้นของ GSON วัตถุ NULL จะถูกละเว้น สิ่งนี้สามารถทำให้รูปแบบเอาต์พุต (ซึ่งถือได้ว่าเป็นผลมาจากการทำให้เป็นอนุกรม) เข้มงวดมากขึ้น อย่างไรก็ตามลูกค้าจะต้องกำหนดค่าเริ่มต้นสำหรับมันเพื่อให้ JSON สามารถ deserialize ตามปกติ
หากคุณต้องการสร้างอินสแตนซ์ GSON Serializable Null คุณสามารถ:
GSON GSON = new gsonBuilder (). serializenulls (). สร้าง ();
โปรดทราบว่าเมื่อ serializing null องค์ประกอบ jsonnull จะถูกเพิ่มลงในโครงสร้าง jsonelement ดังนั้นเราสามารถใช้วัตถุนี้ (GSON) ใน serializer/deserializer ที่กำหนดเองของเรา
นี่คือตัวอย่าง:
ชั้นเรียนสาธารณะ Foo {String Private Final S; INT สุดท้ายส่วนตัว I; public foo () {this (null, 5); } public foo (String s, int i) {this.s = s; this.i = i; }} gson gson = new gsonBuilder (). serializenulls (). create (); foo foo = new foo (); String json = gson.tojson (foo); system.out.println (json); json = gson.tojson (null);เอาท์พุท:
{"s": null, "i": 5} nullการสนับสนุนเวอร์ชัน
คุณสามารถใช้คำอธิบายประกอบ @Since เพื่อรักษาวัตถุเดียวกันหลายรุ่น คำอธิบายประกอบนี้สามารถใช้กับชั้นเรียนและฟิลด์และจะได้รับการสนับสนุนในวิธีการในอนาคต ในการใช้คุณสมบัตินี้คุณต้องกำหนดค่าอินสแตนซ์ GSON เพื่อละเว้นฟิลด์และวัตถุที่ใหญ่กว่าหมายเลขเวอร์ชันที่แน่นอน หากเวอร์ชันไม่ได้ตั้งค่าในวัตถุ GSON ฟิลด์และคลาสทั้งหมดจะถูกใช้เมื่ออนุกรม/deserializing
คลาสสาธารณะ VersionEdClass {@Since (1.1) สตริงสุดท้ายส่วนตัวใหม่ NewerField; @Since (1.0) สตริงสุดท้ายส่วนตัวนิวฟิลด์; ฟิลด์สตริงสุดท้ายส่วนตัว Public VersionEdClass () {this.newerfield = "ใหม่กว่า"; this.newfield = "ใหม่"; this.field = "เก่า"; }} versionEdClass versionedObject = new versionEdClass (); gson gson = new gsonBuilder (). setVersion (1.0) .Create (); string jsonoutput = gson.tojson gson.tojson (someObject); system.out.println (jsonoutput);เอาท์พุท:
{"Newfield": "ใหม่", "Field": "Old"} {"Newerfield": "Newer", "Newfield": "ใหม่", "Field": "Old"}ไม่รวมฟิลด์จากการทำให้เป็นอนุกรม/deserialization
GSON รองรับการใช้วิธีการมากมายในการลบคลาสฟิลด์และประเภทฟิลด์ หากวิธีการต่อไปนี้ไม่ตรงกับความต้องการของคุณคุณสามารถใช้วิธีการทำให้เป็นอนุกรม/deserializer ที่กำหนดเอง
1. การแยกตัวดัดแปลงจาวา
โดยค่าเริ่มต้นหากฟิลด์ถูกประกาศว่าเป็นชั่วคราวฟิลด์จะถูกแยกออก นอกจากนี้หากมีการประกาศฟิลด์แบบคงที่ฟิลด์นี้จะถูกแยกออกโดยค่าเริ่มต้น หากคุณต้องการรวมบางฟิลด์ที่ประกาศว่าเป็นชั่วคราวคุณสามารถทำได้:
นำเข้า java.lang.reflect.modifier; GSON GSON = ใหม่ gsonBuilder () .excludefieldswithmodifiers (modifier.static) .Create ();
โปรดทราบว่าในวิธี Excludefieldswithmodifiers คุณสามารถใช้ค่าคงที่ตัวดัดแปลงให้ได้มากที่สุด ตัวอย่างเช่น:
GSON GSON = ใหม่ gsonBuilder () .ExcludeFieldSwithModifiers (modifier.static, modifier.transient, modifier.volatile) .Create ();
2. ใช้ฟิลด์ @expose เพื่อแยกออก
คุณลักษณะนี้ช่วยให้คุณสามารถติดแท็กฟิลด์เฉพาะในชั้นเรียนเพื่อไม่ให้ถูกแยก/แยกออกในการทำให้เป็นอนุกรม/deserialization ในการใช้คำอธิบายประกอบนี้คุณควรสร้าง GSON โดยใช้ gsonBuilder ใหม่ (). Excludefieldswithoutexposeannotation (). สร้าง () อินสแตนซ์ GSON จะยกเว้นฟิลด์ทั้งหมดในคลาสที่ไม่ได้ทำเครื่องหมายโดย @Expose
3. นโยบายการยกเว้นที่ผู้ใช้กำหนด
หากวิธีการยกเว้นข้างต้นไม่สามารถตอบสนองความต้องการได้คุณสามารถปรับแต่งกลยุทธ์การยกเว้นของคุณได้ สำหรับข้อมูลเพิ่มเติมโปรดดูที่ ExclusionsTrategy Javadoc
ตัวอย่างต่อไปนี้แสดงวิธียกเว้นฟิลด์ที่ทำเครื่องหมายด้วย @FOO และยกเว้นประเภทสตริงระดับสูงสุดหรือประเภทฟิลด์ที่ประกาศ:
@Retention (RetentionPolicy.Runtime) @Target ({ElementType.field}) สาธารณะ @Interface foo {// แท็กฟิลด์เท่านั้นที่มีคำอธิบายประกอบ} ระดับสาธารณะตัวอย่างตัวอย่างที่ Fortest {@foo ส่วนตัว สตริงสตริงสุดท้ายส่วนตัว; Longfield รอบสุดท้ายส่วนตัว; คลาสสุดท้ายส่วนตัว <?> Clazzfield; Public SampleObjectFortest () {AnnotatedField = 5; StringField = "SomedefaultValue"; Longfield = 1234; }} คลาสสาธารณะ MyExClusionsTrategy ใช้ ExclusionSTRATEGY {คลาสสุดท้ายระดับสุดท้าย <?> typetOskip; ส่วนตัว myexclusionstrategy (คลาส <?> typetoskip) {this.typetoskip = typetoskip; } บูลีนสาธารณะควรได้รับ (คลาส <?> clazz) {return (clazz == typetoskip); } บูลีนสาธารณะควรใช้ SKIPField (FieldAttributes f) {return f.getAnnotation (foo.class)! = null; }} โมฆะคงที่สาธารณะหลัก (สตริง [] args) {GSON GSON = ใหม่ gsonBuilder () .SetexClusionStrategies (ใหม่ myExClusionStrategy (string.class)) .serializenulls () .create (); SampleObjectStest SRC = ใหม่ sampleObjectFortest (); สตริง json = gson.tojson (src); System.out.println (JSON); -เอาท์พุท:
{"Longfield": 1234}สนับสนุนการตั้งชื่อฟิลด์ JSON
กลยุทธ์การตั้งชื่อฟิลด์ที่กำหนดไว้ล่วงหน้าบางอย่างของ GSON สามารถแปลงชื่อฟิลด์ Java มาตรฐาน (นั่นคือ Camel Premenclature เช่น SamplefieldNameInjava) เป็นชื่อฟิลด์ JSON (นั่นคือ sample_field_name_in_java หรือ samplefieldnameinjava) สำหรับข้อมูลเพิ่มเติมโปรดดูที่ FieldNamingPolicy
GSON ยังมีนโยบายตามคำอธิบายประกอบเพื่อให้ลูกค้าสามารถปรับแต่งชื่อของฟิลด์ ภายใต้กลยุทธ์นี้หากมีการระบุชื่อฟิลด์ที่ผิดกฎหมายเป็นค่าคำอธิบายประกอบ GSON จะทำการยกเว้นรันไทม์
ตัวอย่างต่อไปนี้แสดงวิธีการใช้กลยุทธ์การตั้งชื่อ GSON ทั้งสองนี้:
คลาสส่วนตัว someObject {@SerializedName ("custom_naming") สตริงสุดท้ายส่วนตัวบางฟิลด์; สตริงสุดท้ายส่วนตัว Someotherfield; Public SomeObject (String A, String B) {this.somefield = a; this.someotherfield = b; }} someObject someObject = new someObject ("First", "Second"); gson gson = new gsonBuilder (). setfieldnamingpolicy (fieldnamingpolicy.upper_camel_case)เอาท์พุท:
{"custom_naming": "First", "Someotherfield": "Second"}หากคุณต้องการปรับแต่งชื่อคุณสามารถใช้คำอธิบายประกอบ @SerializedName
การแบ่งปันสถานะระหว่าง serializer และ deserializer
บางครั้งคุณจะต้องแบ่งปันสถานะระหว่าง serializer และ deserializer และคุณสามารถใช้สามวิธีต่อไปนี้เพื่อให้บรรลุเป้าหมายของคุณ:
สองวิธีแรกไม่ปลอดภัยที่สามคือสามคือ
วิธีแก้ไขข้อผิดพลาดของ GSON แยกกัน
ข้อเสียอย่างหนึ่งของ GSON คือมันไม่สามารถตั้งค่าการเปลี่ยนโมฆะได้
เราสามารถแทนที่ NULL ที่ส่งคืนโดยเซิร์ฟเวอร์ด้วยตนเองในแบทช์เท่านั้น เมื่อมีการกำหนดอินเทอร์เฟซปกติเซิร์ฟเวอร์จะไม่ได้รับอนุญาตให้ส่งคืนค่า NULL แต่ผลลัพธ์พื้นหลังจะปรากฏขึ้นเสมอ!
หากคุณค้นหามีคำตอบทั่วไป
GSON GSON = new gsonBuilder (). serializenulls (). สร้าง ();
แต่สิ่งนี้ไม่สามารถแก้ปัญหาความเท่าเทียมได้วิธีการแก้ปัญหา?
การแก้ปัญหามีดังนี้:
GSON GSON = new GsonBuilder (). registertypeadapterfactory (ใหม่ nullstringtoEmpyAdapterfactory ()). สร้าง (); // จากนั้นใช้ GSON ที่เขียนในบรรทัดด้านบนเพื่อทำให้เป็นอนุกรม nullStringToEmpyAdapterFactory <t> ใช้ typeadapterfactory {@suppresswarnings ("ไม่ถูกตรวจสอบ") สาธารณะ <t> typeadapter <t> สร้าง (gson gson, typetoken <t> ประเภท) {คลาส <t> rawtype = (คลาส <t>) type.getrawtype (); if (rawtype! = string.class) {return null; } return (typeadapter <t>) stringnulladapter ใหม่ (); }} // stringnulladapter คลาสสาธารณะคลาส Stringnulladapter ขยาย typeadapter <string> {@Override สตริงสาธารณะอ่าน (jsonreader reader) พ่น ioexception {// toDo วิธีการที่สร้างอัตโนมัติ asstnult (reader.peek () == กลับ ""; } return reader.nextString (); } @Override โมฆะสาธารณะเขียน (นักเขียน jsonWriter, ค่าสตริง) พ่น IOException {// วิธีการที่สร้างขึ้นอัตโนมัติ stub stub ถ้า (value == null) {writer.nullValue (); กลับ; } writer.value (ค่า); -