ในแง่ของคนธรรมดา Jackson เป็นไลบรารีคลาส Java ที่ใช้ในการประมวลผลข้อมูลรูปแบบ JSON และประสิทธิภาพของมันดีมาก บทความนี้จะให้ตัวอย่างการวิเคราะห์การใช้งาน Jackson ที่ละเอียดยิ่งขึ้น รายละเอียดมีดังนี้:
1. บทนำ
Jackson มีประสิทธิภาพในการซีเรียลไลซ์เซชันและดีซีเรียลไลเซชันค่อนข้างสูง จากการทดสอบ ไม่ว่าจะเป็นการแปลงรูปแบบใด Jackson > Gson > Json-lib และพลังการประมวลผลของ Jackson นั้นสูงกว่า Json-lib เกือบ 10 เท่า และมันก็ถูกต้องเช่นกัน สูงมาก. ในทางตรงกันข้าม ดูเหมือนว่า Json-lib จะหยุดการอัปเดตแล้ว และเวอร์ชันล่าสุดก็ใช้ JDK15 เช่นกัน ในขณะที่ชุมชน Jackson มีการใช้งานมากขึ้น
ด้านล่างนี้เราจะแนะนำการใช้งานของแจ็คสันโดยย่อพร้อมตัวอย่าง
2. การใช้งาน
Jackson มีคลาสและวิธีการมากมาย และคลาสที่ใช้บ่อยที่สุดในการทำให้เป็นซีเรียลไลซ์และดีซีเรียลไลซ์คือคลาส ObjectMapper ซึ่งคล้ายกับ JsonObject และ ArrayObject ใน Json-lib คลาสนี้จัดให้มีวิธีการเช่น readTree(), readValue(), writeValueAsString() สำหรับการแปลง ที่อยู่เอกสารเฉพาะสำหรับคลาสนี้คือ: http://jackson.codehaus.org/1.7.9/javadoc/org/codehaus/jackson/map/ObjectMapper.html
เพื่อหลีกเลี่ยงคำอธิบายซ้ำ objectMapper ที่กล่าวถึงด้านล่างทั้งหมดมาจาก ObjectMapper objectMapper = new ObjectMapper() การใช้งานจะแนะนำสั้นๆ ด้านล่างในแง่ของการทำให้เป็นอนุกรมและดีซีเรียลไลซ์
1. การทำให้เป็นอนุกรม
① ทำให้คลาสของ Java เป็นอนุกรม
ตัวอย่างการทดสอบ
รายการ list=new ArrayList();list.add(1);list.add(2);list.add(3);
ใช้การทำให้เป็นอนุกรม:
สตริง teststringlist=objectMapper.writeValueAsString(list);System.out.println(teststringlist);
ผลลัพธ์ผลลัพธ์บนคอนโซลคือ:
[1,2,3]
สรุปแล้ว:
แจ็กสันสามารถใช้การทำให้เป็นอนุกรมของประเภททั่วไปได้อย่างง่ายดาย
②การทำให้คลาสที่กำหนดเองเป็นอนุกรม
ตัวอย่างการทดสอบ:
นักเรียนชั้นเรียนสาธารณะ {private int age=10;private String name="hhh"; public String[] list={"hao", "haouhao", "keyi"}; public Date time=new Date(); () { อายุที่ส่งคืน; } setAge เป็นโมฆะสาธารณะ (ชื่อสตริง) { this.name = ชื่อ; -
เพื่อให้ตัวอย่างเป็นแบบทั่วไปมากขึ้น คลาสนี้ประกอบด้วยประเภทค่า int, ประเภทการอ้างอิง สตริง, สตริง[] และประเภทวันที่ วันที่
ดำเนินการทำให้เป็นอนุกรม
นักเรียน st = นักเรียนใหม่ (); สตริง teststringstu = objectMapper.writeValueAsString (st); System.out.println (teststringstu);
ผลลัพธ์ผลลัพธ์บนคอนโซลคือ:
{"list":["hao", "haouhao", "keyi"],"time":1375429228382,"name": "hhh", "อายุ":10}
สรุปแล้ว:
จากเอาต์พุตจะเห็นได้ว่าสตริง Json ที่แปลงแล้วสอดคล้องกับรูปแบบ อย่างไรก็ตาม การแสดงเวลายังต่ำกว่ามาตรฐานเล็กน้อย การปรับเปลี่ยนรูปแบบเวลาจะแจ้งให้ทราบด้านล่าง
3.คำจำกัดความของรูปแบบเวลา
Jackson มีรูปแบบเวลาเริ่มต้นของตัวเอง ซึ่งอยู่ในรูปแบบของการประทับเวลา และเอฟเฟกต์ดังที่แสดงในผลลัพธ์ด้านบน (ตัวอย่าง: 1375429228382) หากคุณต้องการตั้งค่ารูปแบบนี้ไม่ถูกต้อง ให้ผ่าน
objectMapper.configure (SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS เท็จ)
สามารถตั้งค่าเพื่อให้การสร้างเวลาใช้รูปแบบที่เรียกว่า [ISO-8601 ] ได้ โดยแสดงเวลาคล้ายกับรูปแบบต่อไปนี้: "1970-01-01T00:00:00.000+0000"
แน่นอน คุณยังสามารถปรับแต่งรูปแบบเวลาเอาท์พุตได้อีกด้วย
การใช้รูปแบบเวลาที่กำหนดเอง
ตัวอย่างยังใช้ชั้นเรียนของนักเรียนที่แนะนำข้างต้น
นักเรียน st=นักเรียนใหม่();java.text.DateFormat myFormat = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss");objectMapper.getSerializationConfig().setDateFormat(myFormat);String teststringstu= objectMapper.writeValueAsString(st);System.out.println(teststringstu);
ผลลัพธ์ demerit บนคอนโซลคือ:
{"list":["hao", "haouhao", "keyi"],"time": "2013-08-02 03:48:20", "name": "hhh", "อายุ":10}
สรุปแล้ว:
จะเห็นได้ว่ารูปแบบเอาต์พุตเวลากลายเป็นสิ่งที่เราต้องการแล้ว วิธีการกำหนดรูปแบบเอาต์พุตเวลาใน Jackson นั้นง่ายกว่าการกำหนดรูปแบบเวลาใน Json-lib มาก
④ วิธีการซีเรียลไลซ์แบบอื่น
ดำเนินการทำให้เป็นอนุกรม
ตัวอย่างที่ใช้ยังคงเป็นชั้นเรียนของนักเรียนคนก่อน
นักเรียน st = นักเรียนใหม่ (); JsonGenerator jsonGenerator = objectMapper.getJsonFactory (). createJsonGenerator (System.out, JsonEncoding.UTF8); jsonGenerator.writeObject (st); System.out.println ();
ผลลัพธ์บนคอนโซลคือ:
{"list":["hao", "haouhao", "keyi"],"time":1375429228382,"name": "hhh", "อายุ":10}
สรุปแล้ว:
วิธีนี้ยังสามารถรับค่าของวิธีการข้างต้นได้ แต่ให้ใส่ใจกับฟังก์ชันนี้ในเมธอดนี้: createJsonGenerator() ซึ่งต้องใช้พารามิเตอร์สองตัว ตัวหนึ่งคือพารามิเตอร์ประเภท OutputStream และอีกตัวคือพารามิเตอร์ประเภท JsonEncoding ด้วยพารามิเตอร์ทั้งสองนี้ เราสามารถเข้าใจได้ว่าวิธีนี้ไม่เพียงแต่สามารถเขียน Json ไปยังสตรีมเครือข่ายได้โดยตรง แต่ยังเขียน Json ไปยังสตรีมไฟล์หรือสตรีมหน่วยความจำได้อีกด้วย ดังนั้นจึงมีความหลากหลายมากขึ้น
2. ดีซีเรียลไลเซชัน
①การดีซีเรียลไลซ์แบบครั้งเดียว
วิธีการนี้ส่วนใหญ่ใช้วิธี <testJsonClass> readValue (เนื้อหาสตริง, Class <testJsonClass> valueType) ที่จัดทำโดย ObjectMapper วิธีการนี้จำเป็นต้องป้อนสตริง Json และคลาสที่สอดคล้องกันของคลาสที่ต้องเติม และส่งกลับคลาสที่เติม
แยกสตริง Json เป็นคลาสที่กำหนดเอง
เมื่อสตริง Json คือ:
สตริง test1="{"objectID":357,"geoPoints":[{"x":504604.59802246094,"y":305569.9150390625}]}"
เวลา.
ขั้นแรกให้กำหนดคลาส:
testJsonClass คลาสสาธารณะ { public int objectID; geoPoints รายการสาธารณะ = new ArrayList ();}
จากนั้นใช้ข้อมูลโค้ดต่อไปนี้เพื่อดีซีเรียลไลซ์ Json ลงในคลาสนี้:
testJsonClass testClass= objectMapper.readValue (ทดสอบ 1, testJsonClass.class);
ใช้
System.out.println(testClass.objectID);System.out.println(testClass.geoPoints)
ค่าที่คุณเห็นเอาต์พุตบนคอนโซลคือ:
357[{x=504604.59802246094, y=305569.9150390625}]
ดีซีเรียลไลซ์สตริง Json ลงในคลาสของระบบเอง เมื่อสตริง Json เป็น
สตริง json = "{"error":0,"data":{"name:"ABC","age":20,"phone":{"home": "abc" "มือถือ": def "}," เพื่อน":[{"ชื่อ":DEF","โทรศัพท์" :{"home""hij"" "มือถือ" "klm"} ชื่อ "GHI" "โทรศัพท์":{"home" "nop" "มือถือ" "qrs"} }]},"อื่นๆ":{"ชื่อเล่น":[]}}"
กำหนดตัวแปรโดยใช้แผนที่ของระบบ: แผนที่ Map<String, Map<String, Object>> จากนั้นใช้ map = objectMapper.readValue(json, Map.class) เพื่อดีซีเรียลไลซ์ Json ลงในแมปตัวแปร
ผ่าน
System.out.println(maps.get("ข้อผิดพลาด"));System.out.println((Object)(maps.get("data").get("โทรศัพท์")))
คุณสามารถรับผลลัพธ์ต่อไปนี้ในคอนโซล:
0{บ้าน=abc, มือถือ=def}
②การดีซีเรียลไลซ์แบบค่อยเป็นค่อยไป
วิธีนี้จะมีความยืดหยุ่นมากกว่าและสามารถแยกเฉพาะค่าข้อมูลสตริง Json ที่ผู้ใช้สนใจได้ ส่วนใหญ่จะนำไปใช้โดยใช้ readTree จัดทำโดย ObjectMapper และคลาส JsonNode จัดทำโดย Jackson
ตัวอย่างการทดสอบ
สตริง ทดสอบ="{"ผลลัพธ์":[{"objectID":357,"geoPoints":[{"x":504604.59802246094,"y":305569.915039 0625}] วิหาร objectID":358,"geoPoints":[{"x":504602.2680053711,"y":305554.43603515625}]}]}";
สตริง Json นี้ค่อนข้างซับซ้อน รวมถึงรูปแบบของอาร์เรย์ที่ซ้อนกัน และเป็นสากล
ดำเนินการดีซีเรียลไลเซชัน
JsonNode node= objectMapper.readTree(test); //อ่านสตริง Json ลงในหน่วยความจำในโครงสร้างต้นไม้ JsonNode contents=node.get("results");//รับข้อมูลภายใต้โหนดผลลัพธ์สำหรับ(int i=0 ; i<contents.size();i++) //สำรวจข้อมูลภายใต้ผลลัพธ์ ฟังก์ชัน size() สามารถรับจำนวนข้อมูลที่มีอยู่ในโหนด ซึ่งคล้ายกับความยาวของอาร์เรย์ {System.out.println(contents.get(i).get("objectID" ). getIntValue()); // อ่านค่าของโหนดย่อยภายใต้โหนด JsonNode geoNumber=contents.get(i).get("geoPoints");for(int j=0;j<geoNumber.size();j++) //วนซ้ำข้อมูลภายใต้โหนดลูก {System.out.println(geoNumber.get(j).get("x").getDoubleValue()+" " +geoNumber.get(j).get("y").getDoubleValue());}}
ผลลัพธ์บนคอนโซลคือ:
357504604.59802246094 305569.9150390625358504602.2680053711 305554.43603515625
สรุปแล้ว:
วิธีนี้จะคล้ายกับการแยกวิเคราะห์ DOM ในการแยกวิเคราะห์ XML ข้อดีคือโครงสร้างมีรายละเอียด ทำให้ง่ายต่อการดึงข้อมูลที่ต้องการ แน่นอนว่าข้อเสียก็เหมือนกับวิธีนี้: ต้องใช้เวลาและพื้นที่
3. สรุป
การดำเนินการของ Jackson บน Json ส่วนใหญ่จะเป็นไปตามที่แสดงไว้ด้านบน วิธีการนี้สะดวกในการใช้งานและมีความยืดหยุ่นมาก โดยให้การดำเนินการแบบครั้งเดียวและการดำเนินการที่สามารถอ่านข้อมูลได้ตามความต้องการ และแจ็คสันมีฟังก์ชันต่างๆ มากมาย ซึ่งสามารถควบคุมซีเรียลไลซ์เซชันและดีซีเรียลไลซ์ในรายละเอียดต่างๆ ได้ เช่น ฟังก์ชันคำอธิบายประกอบ ฟังก์ชันการหน่วงเวลาสำหรับไฮเบอร์เนต และฟังก์ชันการตั้งค่ารูปแบบเวลา เนื่องจากในปัจจุบันไม่จำเป็นต้องใช้ฟังก์ชันเหล่านี้ โปรดศึกษาให้ดี สำหรับภายหลัง ในเวลาเดียวกัน Jackson ยังสนับสนุนชุดของการดำเนินการซีเรียลไลซ์เซชันและดีซีเรียลไลซ์บน XML แนวคิดนี้เหมือนกับการแยกวิเคราะห์ Json โดยประมาณ
เกี่ยวกับข้อบกพร่องในปัจจุบันของ Jackson บางคนบนอินเทอร์เน็ตได้ทดสอบแล้วว่าใช้หน่วยความจำมากกว่า Json-lib การใช้พื้นที่เพื่อเวลาโดยทั่วไปถือว่าคุ้มค่า