แบ็กเอนด์ให้บริการมักจะส่งคืนสตริง JSON แต่ในบางสถานการณ์อาจจำเป็นต้องส่งคืนสตรีมไบนารีโดยตรงเช่นอินเทอร์เฟซการแก้ไขรูปภาพโดยหวังว่าจะส่งคืนสตรีมภาพโดยตรงไปยังส่วนหน้า เวลานี้สามารถทำอะไรได้บ้าง?
การใช้งานหลักคือวัตถุ httpservletresponse และเคสถูกนำไปใช้ดังนี้
@RequestMapping (value = {"/img/render"}, method = {requestMethod.get, requestMethod.post, requestMethod.options})@crossorigin (origins = "*")@responsebodypublic encute IMG เป็นกระแสไบนารีของไบต์ภาพ [] img = xxx; httpservletResponse.setContentType ("image/png"); OutputStream OS = httpservletResponse.getOutputStream (); OS.WRITE (IMG); os.flush (); os.close (); กลับ "ความสำเร็จ";}สิ่งที่ควรทราบ
โดยทั่วไปแล้วอินเทอร์เฟซบริการที่ได้รับจากแบ็กเอนด์มักจะส่งคืนข้อมูล JSON ดังที่ได้กล่าวไว้ก่อนหน้านี้ฉากของภาพที่กลับมาโดยตรงดังนั้นวิธีทั่วไปในการคืนรูปภาพคืออะไร?
ดังนั้นคอนโทรลเลอร์ที่เราควรให้การสนับสนุนสำหรับท่าทางการใช้งานสามอันข้างต้นในเวลาเดียวกัน?
เนื่องจากมีหลายวิธีในการกลับมาเป็นวิธีที่จะเลือกแน่นอนว่ามันถูกระบุโดยส่วนหน้าดังนั้นคุณสามารถกำหนดวัตถุถั่วที่ร้องขอพารามิเตอร์
@Datapublic คลาส BaseRequest {ส่วนตัวคงที่สุดท้าย Long SerialVersionUID = 1146303518394712013L; / ** * เมธอดเอาท์พุท: * * url: ที่อยู่ HTTP (วิธีเริ่มต้น) * BASE64: การเข้ารหัส BASE64 * สตรีม: ภาพส่งคืนโดยตรง * */ สตริงส่วนตัว outType; /*** ส่งคืนประเภทภาพ* JPG | PNG | Webp | gif */ สตริงส่วนตัว mediaType; สาธารณะ returntypeenum returntype () {return returntypeen.getenum (outtype); } Public MediaTypeenum MediaType () {return mediaTypeenum.getenum (MediaType); -เพื่อให้การตัดสินง่ายขึ้นมีการกำหนดคำอธิบายประกอบสองอันหนึ่งรายการกลับมาและ mediaTypeenum อื่น ๆ แน่นอนความจำเป็นนั้นไม่ค่อยดีนัก ต่อไปนี้เป็นคำจำกัดความของทั้งสอง
public enum returntypeenum {url ("url"), สตรีม ("สตรีม"), base64 ("ฐาน"); ประเภทสตริงส่วนตัว returnTypeenum (ประเภทสตริง) {this.type = type; } แผนที่คงที่ส่วนตัว <สตริง, returntypeenum> แผนที่; คงที่ {map = new hashmap <> (3); สำหรับ (returntypeenum e: returntypeenum.values ()) {map.put (e.type, e); }} สาธารณะ returnTypeenum getenum (ประเภทสตริง) {ถ้า (type == null) {return url; } returnTypeenum e = map.get (type.toLowerCase ()); return e == null? URL: E; - @datapublic enum mediaTypeenum {imagejpg ("jpg", "image/jpeg", "ffd8ff"), imagegif ("gif", "image/gif", "47494638"), imagepng ("png", "ภาพ/png" "Image/Webp", "52494646"), String Final Private Final String Ext; MIME สตริงสุดท้ายส่วนตัว; มายากลสตริงสุดท้ายส่วนตัว; MediaTypeenum (String Ext, String Mime, String Magic) {this.ext = ext; this.mime = mime; this.magic = Magic; } แผนที่แบบคงที่ส่วนตัว <String, MediaTypeenum> แผนที่; คงที่ {map = ใหม่ hashmap <> (4); สำหรับ (mediaTypeenum e: ค่า ()) {map.put (e.getExt (), e); }} public Static mediaTypeenum getenum (ประเภทสตริง) {ถ้า (type == null) {return imagejpg; } mediaTypeenum e = map.get (type.toLowerCase ()); return e == null? ImageJPG: E; -ข้างต้นคือถั่วที่ห่อหุ้มด้วยพารามิเตอร์คำขอ แน่นอนว่ายังมีถั่วที่สอดคล้องกันที่จะกลับมา
@Datapublic คลาส baseresponse { / *** ส่งคืนเส้นทางสัมพัทธ์ของภาพ* / พา ธ สตริงส่วนตัว; / *** ส่งคืนรูปแบบ https ของ image*/ url สตริงส่วนตัว; / *** รูปภาพในรูปแบบ Base64*/ ฐานสตริงส่วนตัว;}ภาพประกอบ:
ในสภาพแวดล้อมโครงการจริงพารามิเตอร์การร้องขอและการส่งคืนจะไม่ง่ายอย่างที่ข้างต้นดังนั้นคุณสามารถนำไปใช้งานได้โดยการสืบทอดถั่วข้างต้นหรือกำหนดรูปแบบที่เกี่ยวข้องด้วยตัวคุณเอง
เนื่องจากเป้าหมายชัดเจนบรรจุภัณฑ์จึงเป็นขั้นตอนที่ชัดเจนที่สุดในเรื่องนี้
void buildResponse (คำขอ baseRequest, การตอบสนอง baseresponse, byte [] bytes) โยน selferror {switch (request.returntype ()) {case url: อัปโหลด (ไบต์, การตอบสนอง); หยุดพัก; CASE BASE64: BASE64 (ไบต์การตอบสนอง); หยุดพัก; สตรีมเคส: สตรีม (ไบต์คำขอ); }} การอัปโหลดโมฆะส่วนตัว (ไบต์ [] ไบต์, การตอบสนอง baseresponse) พ่น selferror {ลอง {// อัปโหลดไปยังเซิร์ฟเวอร์รูปภาพและแทนที่เส้นทางสตริง = uploadutil.upload (ไบต์); if (stringutils.isblank (path)) {// อัปโหลดล้มเหลวโยนใหม่ภายใน (null); } Response.SetPath (เส้นทาง); Response.seturl (cdnutil.img (เส้นทาง)); } catch (ioexception e) {// cdn exception log.error ("อัปโหลดไปยังข้อผิดพลาด cdn! e: {}", e); โยน cdnuploaderror ใหม่ (e.getMessage ()); }} // return base64private void base64 (byte [] bytes, การตอบสนอง baseresponse) {String base = base64.getEncoder (). encodetoString (ไบต์); Response.SetBase (ฐาน);} // ส่งคืนภาพบัญชีแบบไบนารีภาพโมฆะส่วนตัว (ไบต์ [] ไบต์คำขอ baseRequest) พ่น Selferror {ลอง {mediaTypeenum mediaType = request.mediatype (); httpservletResponse servletResponse = ((servletrequestattributes) requestcontextholder.getRequestattributes ()). getResponse (); ServletResponse.setContentType (MediaType.getMime ()); OutputStream OS = servletResponse.getOutputStream (); OS.WRITE (ไบต์); os.flush (); os.close (); } catch (exception e) {log.error ("ข้อผิดพลาดการส่งคืนทั่วไป IMG IMG! req: {}, e: {}", คำขอ, e); if (stringutils.isnotblank (e.getMessage ())) {โยนใหม่ภายใน (e.getMessage ()); } else {โยน new InternalError (null); -ภาพประกอบ:
โปรดละเว้นวิธีการยกเว้นที่กำหนดเองข้างต้น เมื่อคุณต้องการใช้พวกเขาคุณสามารถกำจัดข้อยกเว้นที่กำหนดเองเหล่านี้ได้อย่างสมบูรณ์ ที่นี่ฉันพูดสั้น ๆ เกี่ยวกับสาเหตุที่วิธีการยกเว้นแบบกำหนดเองนี้ใช้ในโครงการจริงส่วนใหญ่เป็นเพราะข้อดีต่อไปนี้
ร่วมกับการจับภาพข้อยกเว้นทั่วโลก (ControllerAdvie) มันสะดวกและใช้งานง่ายมาก
ข้อยกเว้นทั้งหมดได้รับการจัดการจากส่วนกลางเพื่ออำนวยความสะดวกในสถิติข้อมูลและการเตือนภัย
ตัวอย่างเช่นหลังจากทำการนับจำนวนข้อยกเว้นในสถานที่ที่รวมเป็นหนึ่งและจากนั้นเกินเกณฑ์ที่กำหนดให้โทรหาบุคคลที่รับผิดชอบดังนั้นจึงไม่จำเป็นต้องฝังจุดในแต่ละสถานที่ที่มีกรณียกเว้นเกิดขึ้น
หลีกเลี่ยงการส่งรหัสสถานะข้อผิดพลาดแบบเลเยอร์โดยเลเยอร์
- นี่เป็นส่วนใหญ่สำหรับบริการเว็บ โดยทั่วไปจะมีรหัสสถานะข้อผิดพลาดที่สอดคล้องกันและข้อความแสดงข้อผิดพลาดในสตริง JSON ที่ส่งคืน
- กรณีข้อยกเว้นอาจปรากฏขึ้นได้ทุกที่ เพื่อรักษาข้อมูลข้อยกเว้นนี้ข้อมูลจะถูกส่งผ่านไปยังเลเยอร์คอนโทรลเลอร์โดยเลเยอร์ หรือพบใน Threadlocal; เห็นได้ชัดว่าวิธีการเหล่านี้ไม่สะดวกในการใช้งาน
แน่นอนว่ามีข้อเสีย:
วิธีการยกเว้นค่าใช้จ่ายเพิ่มเติมประสิทธิภาพเพิ่มเติมดังนั้นในข้อยกเว้นที่กำหนดเองฉันได้ครอบคลุมวิธีการต่อไปนี้ไม่มีสแต็กที่สมบูรณ์
@Overridepublic ซิงโครไนซ์ fillinstacktrace () {return this;}บางคนอาจไม่ชอบวิธีการเข้ารหัสพฤติกรรมนี้
ดูเหมือนจะไม่น่าสนใจที่จะบอกว่าคุณไม่ได้ฝึกฝน การออกแบบข้างต้นสะท้อนให้เห็นอย่างเต็มที่ในโครงการโอเพ่นซอร์สอย่างรวดเร็วสื่อที่ฉันได้รับการดูแลรักษา แน่นอนว่ามีความแตกต่างบางอย่างจากข้างต้น ท้ายที่สุดมันเกี่ยวข้องกับธุรกิจมากขึ้น หากคุณสนใจคุณสามารถอ้างอิงได้
QuickMedia: https://github.com/liuyueyi/quick-media:
Baseaction: com.hust.hui.quickmedia.web.wxapi.wxbaseaction#buildreturn
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น