สรุป
SpringMVC ใช้ตัวแปลงข้อความเพื่อรับรู้การแปลงอัตโนมัติระหว่างข้อความคำขอและวัตถุวัตถุและข้อความตอบกลับ
ใน SpringMVC คุณสามารถใช้สองคำอธิบายประกอบ @RequestBody และ @ResponseBody เพื่อให้การแปลงข้อความร้องขอเป็นวัตถุและวัตถุเป็นข้อความตอบกลับตามลำดับ กลไกการแปลงข้อความที่ยืดหยุ่นพื้นฐานคือ httpmessageConverter ที่เพิ่งเปิดตัวซึ่งเป็นกลไกการแปลงข้อความซึ่งเป็น httpmessageconverter ที่เพิ่งเปิดตัวใหม่ในฤดูใบไม้ผลิ 3.x
สิ่งที่เป็นนามธรรมของคำขอ #HTTP ยังคงกลับไปที่การตอบสนองการร้องขอนั่นคือเพื่อแยกวิเคราะห์ร่างกายคำขอแล้วส่งคืนข้อความตอบกลับ นี่เป็นกระบวนการคำขอ HTTP ขั้นพื้นฐานที่สุด เรารู้ว่าในมาตรฐาน servlet วิธีต่อไปนี้ใน Javax.servlet.servletrequest อินเตอร์เฟสสามารถใช้งานได้:
Public ServletInputStream getInputStream () พ่น IOException;
เพื่อรับ servletInputStream ใน ServletInputStream นี้เนื้อหาทั้งหมดของข้อความคำขอดิบสามารถอ่านได้ ในทำนองเดียวกันในอินเตอร์เฟส javax.servlet.servletResponse สามารถใช้วิธีการต่อไปนี้ได้:
Public ServletOutputStream getOutputStream () พ่น IOException;
ในการรับ servletoutputstream, servletoutputsteam นี้ได้รับการสืบทอดจาก outputstream ใน Java ช่วยให้คุณสามารถส่งออกเนื้อหาแพ็คเก็ตตอบกลับ HTTP
ลองคิดเหมือนนักออกแบบ SpringMVC เรารู้ว่าคำขอ HTTP และแพ็คเก็ตตอบสนองเป็นหลักของสตริง เมื่อแพ็คเก็ตคำขอมาถึง Java World มันจะถูกห่อหุ้มไว้ในสตรีมอินพุต servletInputStream เพื่อให้เราอ่านแพ็กเก็ต ข้อความตอบกลับคือเอาต์พุตผ่านกระแสเอาต์พุตของ servletoutputstream
เราสามารถอ่านข้อความสตริงต้นฉบับจากสตรีมและในทำนองเดียวกันเราสามารถเขียนอักขระดั้งเดิมลงในสตรีมเอาต์พุตเท่านั้น ในโลกชวาการประมวลผลตรรกะทางธุรกิจขึ้นอยู่กับวัตถุเฉพาะทางธุรกิจเป็นมิติการประมวลผล จากนั้นเมื่อข้อความมาถึง SpringMVC และออกจาก SpringMVC จะมีปัญหาความต้านทานระหว่างสตริงและวัตถุ Java กระบวนการนี้ไม่สามารถแปลงด้วยตนเองโดยนักพัฒนา เรารู้ว่าใน struts2 OGNL ใช้เพื่อจัดการกับปัญหานี้ในขณะที่ใน SpringMVC มันเป็นกลไก HTTPMessageConverter ลองดูที่อินเทอร์เฟซทั้งสองก่อน
#httpinputMessage คลาสนี้เป็นนามธรรมของข้อความคำขอ HTTP ภายใน SpringMVC ในวิธีการอ่าน () ของ httpmessageConverter มีพารามิเตอร์อย่างเป็นทางการของ httpinputMessage ซึ่งเป็นนามธรรมภายในของตัวรับ "ข้อความร้องขอ" ที่ใช้โดยตัวแปลงข้อความของ SpringMVC ตัวแปลงข้อความดึงข้อความจาก "ข้อความร้องขอ" ตามกฎและแปลงเป็นวัตถุที่ประกาศในพารามิเตอร์วิธีการอย่างเป็นทางการ
แพ็คเกจ org.springframework.http; นำเข้า java.io.ioexception; นำเข้า java.io.inputstream; อินเตอร์เฟสสาธารณะ httpinputMessage ขยาย httpmessage {inputstream getbody () โยน ioexception;}}}#HTTTPOUTPUTMESSAGE คลาสนี้เป็นนามธรรมของข้อความตอบกลับ HTTP ภายใน SpringMVC ในวิธีการเขียน () ของ httpmessageConverter มีพารามิเตอร์อย่างเป็นทางการของ httpoutputMessage ซึ่งเป็นนามธรรมภายในของตัวรับ "ข้อความตอบกลับ" ที่ใช้โดยตัวแปลงข้อความของ SpringMVC ตัวแปลงข้อความเขียน "ข้อความตอบกลับ" ลงในข้อความตอบกลับตามกฎบางอย่าง
แพ็คเกจ org.springframework.http; นำเข้า java.io.ioException; นำเข้า java.io.outputStream; อินเตอร์เฟสสาธารณะ httpoutputMessage ขยาย httpmessage {outputstream getbody () โยน ioexception;}}}#HTTPMESSAGECONVERTER อินเตอร์เฟสระดับสูงสุดที่เป็นนามธรรมของตัวแปลงข้อความอธิบายลักษณะทั่วไปของตัวแปลงข้อความ เราสามารถเข้าใจกระบวนการคิดของนักออกแบบ Spring3.x เกี่ยวกับกลไกนี้จากวิธีการที่กำหนดไว้ในอินเทอร์เฟซนี้
แพ็คเกจ org.springframework.http.converter; นำเข้า java.io.ioexception; นำเข้า java.util.list; นำเข้า org.springframework.http.httpinputMessage; นำเข้า org.springframework.http.mediatype; อินเตอร์เฟสสาธารณะ httpmessageConverter <t> {boolean canread (คลาส <?> clazz, mediaType mediaType); บูลีน canwrite (คลาส <?> clazz, mediaType mediaType); รายการ <MediaType> getSupportedmediatypes (); t อ่าน (คลาส <? ขยาย t> clazz, httpinputMessage inputMessage) พ่น IOException, httpmessagenotreadableException; โมฆะเขียน (T T, MediaType ContentType, HttpOutputMessage outputMessage) พ่น IOException, httpMessagenotwritable Exception;}คำจำกัดความของอินเตอร์เฟส httpmessageConverter ได้จับคู่ canread (), read () และ canWrite (), วิธีการเขียน () MediaType คือการห่อหุ้มแอตทริบิวต์ประเภทสื่อที่ร้องขอ ตัวอย่างเช่นเมื่อเราประกาศวิธีการประมวลผลต่อไปนี้
@RequestMapping (value = "/string", method = requestMethod.post) public @ResponseBody string readstring (@requestbody สตริงสตริง) {return "read string '" + string + "";}ก่อนที่ SpringMVC จะเข้าสู่วิธีการอ่านข้อมูลจะเลือกคลาสการใช้งาน HTTPMESSAGECONVERTER ที่เหมาะสมตามคำอธิบายประกอบ @RequestBody เพื่อแยกวิเคราะห์พารามิเตอร์คำขอลงในตัวแปรสตริง โดยเฉพาะคลาส StringhttpMessageConverter ใช้ เมธอด canread () จะส่งคืนจริงจากนั้นวิธีการอ่าน () จะอ่านพารามิเตอร์คำขอจากคำขอและผูกกับตัวแปรสตริงของวิธี readstring ()
เมื่อ SpringMVC ดำเนินการวิธีการอ่านค่าใช้จ่ายเนื่องจากค่าส่งคืนจะระบุ @ResponseBody, SpringMVC จะใช้วิธีการเขียน () ของ StringhttpMessageConverter และเขียนผลลัพธ์เป็นค่าสตริงไปยังข้อความตอบกลับ แน่นอนเมธอด canWrite () กลับมาเป็นจริงในเวลานี้
เราสามารถใช้ตัวเลขต่อไปนี้เพื่ออธิบายกระบวนการนี้สั้น ๆ
#requestresponsebodymethodprocessor คลาสที่อธิบายไว้ในชุดกระบวนการข้างต้นคือ org.springframework.web.servlet.mvc.method.annotation.requestresponsebodymethodprocessor คลาสนี้ใช้ทั้ง handlerermethodargumentResolver และ handlermethodreturnvalueHandler อดีตเป็นอินเทอร์เฟซนโยบายที่ผูกข้อความคำขอไปยังพารามิเตอร์อย่างเป็นทางการของวิธีการประมวลผลและหลังเป็นอินเทอร์เฟซนโยบายที่ประมวลผลค่าคืนของวิธีการประมวลผล ซอร์สโค้ดของอินเทอร์เฟซทั้งสองมีดังนี้:
แพ็คเกจ org.springframework.web.method.support; นำเข้า org.springframework.core.methodparameter; นำเข้า org.springframework.web.bind.webdatabinder; org.springframework.web.context.request.nativeWebRequest; อินเตอร์เฟสสาธารณะ handlermethodargumentResolver {boolean supportsparameter (พารามิเตอร์ methodparameter); Object Resolveargument (พารามิเตอร์ MethodParameter, ModelAndViewContainer MavContainer, WebRequest NativeWebrequest, WebDatabinderFactory BindFactory) โยนข้อยกเว้น;} package org.springframework.web.method.support; org.springframework.web.context.request.nativeWebRequest; อินเตอร์เฟสสาธารณะ handlerermethodreturnvalueHandler {boolean supportsreturntype (methodparameter returntype); เป็นโมฆะ HandlerEturnValue (Object returnValue, MethodParameter returnType, ModelAndViewContainer MavContainer, NativeWebRequest WebRequest) โยนข้อยกเว้น;}คลาส RequestResponseBodyMethodProcessor ยังทำหน้าที่เป็นสองบทบาท: การวิเคราะห์พารามิเตอร์วิธีการและการประมวลผลค่าส่งคืน จากซอร์สโค้ดเราสามารถค้นหาการใช้วิธีการของอินเทอร์เฟซสองตัวข้างต้น
การใช้งานอินเทอร์เฟซ HandlermethodargumentResolver:
Public Boolean supportsparameter (พารามิเตอร์ MethodParameter) {return parameter.hasparameterannotation (requestbody.class);} วัตถุสาธารณะ Resolveargument (MethodParameter พารามิเตอร์, ModelandViewContainer MavContainer พารามิเตอร์, พารามิเตอร์. getGenericParameterType ()); ชื่อสตริง = conventions.getVariableNameForAmeter (พารามิเตอร์); WebDatabinder Binder = BindFactory.CreateBinder (WebRequest, อาร์กิวเมนต์, ชื่อ); if (อาร์กิวเมนต์! = null) {ตรวจสอบ (สารยึดเกาะ, พารามิเตอร์); } mavcontainer.addattribute (bindingResult.model_key_prefix + ชื่อ, Binder.getBindingResult ()); อาร์กิวเมนต์ส่งคืน;}การใช้งานอินเทอร์เฟซ HandlermethodreturnValueHandler
Public Boolean supportsreturntype (MethodParameter returnType) {return returnType.getMethodannotation (responsebody.class)! = null;} โมฆะสาธารณะ handlereturnValue (Object returnValue, MethodParameter returnType httpmediatypenotacceptableException {mavcontainer.setRequestHandled (จริง); if (returnValue! = null) {writeWithMessageConverters (returnValue, returnType, webRequest); -หลังจากอ่านรหัสด้านบนแล้วบริบทการแปลงข้อความ HTTPMESSAGECONVERTER ทั้งหมดนั้นชัดเจนมากอยู่แล้ว เนื่องจากการใช้งานของอินเทอร์เฟซทั้งสองนั้นขึ้นอยู่กับว่ามี @requestbody และ @ResponseBody เป็นเงื่อนไขหรือไม่จากนั้น httpmessageConverter เรียกว่าการอ่านและเขียนข้อความตามลำดับ
หากคุณต้องการถามวิธีการติดตาม RequestResponseBodyMethodProcessor โปรดติดตามแนวคิดของโพสต์บล็อกก่อนหน้าแล้วไปที่ Spring-MVC-Showcase เพื่อดาวน์โหลดซอร์สโค้ดและดีบักตัวอย่างที่เกี่ยวข้องกับ HTTPMessageConverter ตราบใดที่คุณเต็มใจที่จะทำงานหนักฉันเชื่อว่าคุณจะได้รับของคุณเองอย่างแน่นอน
#การจับจาง Xiaolong เมื่อพูดถึงสาระสำคัญของ WeChat เขากล่าวว่า: "WeChat เป็นเพียงแพลตฟอร์มและข้อความกำลังหมุนเวียนอยู่ในนั้น" ในกระบวนการวิเคราะห์ซอร์สโค้ด SpringMVC ของเราเราสามารถเข้าใจความจริงที่คล้ายกันจากกลไก HTTPMessageConverter ในสายตาของนักออกแบบ SpringMVC ข้อความคำขอและข้อความตอบกลับจะถูกแยกออกเป็นข้อความคำขอ httpinputMessage และข้อความตอบกลับ httpoutputMessage ตามลำดับ
เมื่อประมวลผลคำขอตัวแปลงข้อความที่เหมาะสมจะเชื่อมโยงข้อความคำขอไปยังวัตถุพารามิเตอร์ที่เป็นทางการในวิธีการ ที่นี่อาจมีหลายรูปแบบข้อความที่แตกต่างกันสำหรับวัตถุเดียวกันเช่น JSON และ XML ในทำนองเดียวกันเมื่อตอบกลับคำขอค่าส่งคืนของวิธีการอาจถูกส่งกลับไปยังรูปแบบข้อความที่แตกต่างกันเช่น JSON และ XML
ใน SpringMVC เรามีคลาสการใช้งาน HTTPMESSAGECONVERTER ที่แตกต่างกันเพื่อจัดการกับรูปแบบข้อความต่าง ๆ สำหรับรูปแบบข้อความที่แตกต่างกัน อย่างไรก็ตามตราบใดที่ "ข้อมูลที่ถูกต้อง" ที่มีอยู่ในข้อความเหล่านี้มีความสอดคล้องกันตัวแปลงข้อความต่าง ๆ จะสร้างผลการแปลงเดียวกัน สำหรับความแตกต่างในการแยกรายละเอียดระหว่างข้อความต่าง ๆ พวกเขาจะถูกบล็อกในคลาสการใช้งาน HTTPMESSAGECONVERTER ที่แตกต่างกัน
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น