พื้นหลัง
เพื่อนที่ใช้สัญชาตญาณที่น่าสงบเพื่อส่งออกความต้องการเหล่านี้ถูกปฏิเสธ ~ มันทำลายความสอดคล้องของ URL ที่สงบสุข [การแก้ไขที่เข้มงวดคือ HTTP JSON หรือ RESTFUL เพื่อนหลายคนจะเปิดเผย JSON และเรียกมันว่าพักผ่อนโดยตรง]
เช่นเดียวกับในเครื่องกำเนิดรหัสด้านบนเราจะสร้างชุดของรหัสซึ่งส่วนใหญ่เป็น RestControllers
บทคัดย่อระดับนามธรรม AbstractrestController <V ขยาย VO, S ขยายดังนั้น PK ขยาย serializable> {คลาสที่ได้รับการป้องกัน <v> voclazz; @AutoWired Private Service <V, S, PK> บริการ; Public AbstractrestController () {typetoken <v> votype = ใหม่ typetoken <v> (getClass ()) {}; voclazz = (คลาส <v>) votype.getrawtype (); } @PostMapping () @apioperation (value = "นิติบุคคลใหม่", notes = "") ผลลัพธ์สาธารณะเพิ่ม (@requestbody v vo) {service.saveselective (VO); return resultGenerator.genSuccessResult (); } @DeleTeMapping ("/{id}") @apioperation (value = "ลบเอนทิตี", notes = "") ผลลัพธ์สาธารณะลบ (@PathVariable pk id) {service.deleteById (id); return resultGenerator.genSuccessResult (); } @putMapping @apioperation (value = "update entity", notes = "") การอัปเดตผลลัพธ์สาธารณะ (@requestbody v vo) {service.updateByBrimaryKeySelective (VO); return resultGenerator.genSuccessResult (); } @getMapping @apioperation (value = "รับรายการเอนทิตี", notes = "") รายการผลลัพธ์สาธารณะ (S SO) {pageHelper.startPage (So.getCurrentPage (), so.getPagesize ()); รายการ <v> list = service.findall (); PageInfo PageInfo = ใหม่ PageInfo (รายการ); ExcelexportParam (); Return ResultGenerator.genSuccessResult (PageInfo); } void void excelexportParam () {exportParams ep = exportParams ใหม่ (null, "data"); ExcelexportParam <v> param = ใหม่ excelexportParam <> (); param.setClazz (VOCLAZZ); param.setexcelexport (excelexport.normalexcel); param.setexportparams (EP); param.setFilename ("file.xls"); f6static.setexcelexportparam (param); } @getMapping ("/{id}") @apioperation (value = "รับเอนทิตีเดี่ยว", notes = "") รายละเอียดผลลัพธ์สาธารณะ (@PathVariable PK ID) {v Vo = Service.findById (ID); Return ResultGenerator.gensuccessResult (VO); } @deletemapping ("/batch") @apioperation (value = "batch delete entity", notes = "") ผลลัพธ์สาธารณะ batchdelete (@requestparam ids สตริง ids) {service.deleteByIds (ID); return resultGenerator.genSuccessResult (); } @getMapping ("/batch") @apioperation (value = "batch get entity", notes = "") ผลลัพธ์สาธารณะ batchdetail (@requestparam ids ids ids) {รายการ <v> vos = service.findbyids (ID); Return ResultGenerator.genSuccessResult (VOS); } @postmapping ("/batch") @apioperation (value = "batch entity ใหม่", notes = "") ผลลัพธ์สาธารณะเพิ่ม (@requestbody list <v> vos) {service.save (vos); return resultGenerator.genSuccessResult (); } @getMapping ("/count") @apioperation (value = "รับจำนวนเอนทิตี", notes = "") จำนวนผลลัพธ์สาธารณะ (@requestbody v v) {int count = service.selectCount (V); return resultGenerator.gensuccessResult (นับ); -แล้วจะส่งออกอย่างไร? [อันที่จริงมันสามารถเข้าใจได้ว่าการส่งออกเป็นการแสดงข้อมูล แต่ผลลัพธ์ไม่ได้เป็นเพียง JSON]
หากมีการตั้งคำถามแล้วการเข้าสู่ระบบ? โซลูชันดั้งเดิมคือการออกจากระบบเข้าสู่ระบบ ดังนั้นความคิดในการแทนที่ทรัพยากรที่น่าพักผ่อนคืออะไร?
เคล็ดลับ: เข้าสู่ระบบเป็นเซสชั่นใหม่ ออกจากระบบคือเซสชันการลบ
ทำให้สำเร็จ
จากแนวคิดข้างต้นเราคิดว่าเราต้องส่งคืนผลลัพธ์หลายรายการไปยัง URL เดียวกันเท่านั้นใช่ไหม [pdf, หนึ่งเวอร์ชัน, หนึ่งเวอร์ชัน, หนึ่งเวอร์ชัน, หนึ่งเวอร์ชัน, หนึ่งเวอร์ชัน, หนึ่งเวอร์ชัน]
บิงโก นี่คือที่มาของการเจรจาต่อรองเนื้อหา
ในความเป็นจริงการเจรจาต่อรองเนื้อหาไม่ได้สร้างขึ้นในฤดูใบไม้ผลิจริง ๆ แล้วสามารถเห็นได้จากส่วนหัว HTTP
1. ตัวอย่างเช่นการกลับไปที่หน้าภาษาอังกฤษไปยังลูกค้าภาษาอังกฤษนั้นมากเกินไปสำหรับหน้าภาษาจีน
โปรโตคอล HTTP กำหนดค่าคุณภาพ (เรียกว่าค่า Q) ที่อนุญาตให้ลูกค้าแสดงรายการตัวเลือกหลายตัวสำหรับแต่ละหมวดหมู่การตั้งค่าและเชื่อมโยงลำดับความสำคัญสำหรับตัวเลือกการตั้งค่าแต่ละตัวเลือก
ยอมรับภาษา: en; q = 0.5, fr; q = 0.0, nl; q = 1.0, tr; q = 0.0
ในกรณีที่ค่า Q อยู่ในช่วง 0.0 ถึง 1.0 (0.0 เป็นลำดับความสำคัญต่ำสุดในขณะที่ 1.0 เป็นลำดับความสำคัญสูงสุด)
โปรดทราบว่าลำดับของการตั้งค่าไม่สำคัญเฉพาะค่า q ที่เกี่ยวข้องกับการตั้งค่าเป็นสิ่งสำคัญ
2. จากนั้นก็มีพารามิเตอร์อื่น ๆ เช่นการยอมรับหัว
โดยปกติแล้วการเจรจาต่อรองเนื้อหาจะมีวิธีแก้ปัญหาดังต่อไปนี้
1. ใช้ส่วนหัวยอมรับ:
นี่คืออธิบายทั่วไปในตำราเรียน เป็นการดีที่วิธีนี้ดีที่สุด แต่ถ้าทรัพยากรของคุณสามารถเข้าถึงได้โดยตรงผ่านเบราว์เซอร์ (เช่นจอแสดงผล HTML) จากนั้นเนื่องจากความแตกต่างของเบราว์เซอร์ส่วนหัวที่รับส่วนหัวที่รับจะแตกต่างกัน สิ่งนี้จะทำให้เซิร์ฟเวอร์ไม่ทราบว่ารูปแบบของข้อมูลที่จะกลับมาหาคุณ ต่อไปนี้เป็นส่วนหัวที่ยอมรับของเบราว์เซอร์
Chrome: ยอมรับ: แอปพลิเคชัน/XML, แอปพลิเคชัน/XHTML+XML, TextMl; q = 0.9, ข้อความ/ธรรมดา; q = 0.8, รูปภาพ/png,*/*; q = 0.5 firefox: ยอมรับ: ข้อความ/html, application/xhtml+xml, แอปพลิเคชัน/xml; q = 0.9,*/*; Image/PJPEG, Application/X-Shockwave-Flash, Application/X-Silverlight, Application/X-MS-Application, Application/X-MS-XBAP, Application/VND.MS-XPSDocument, Application/XAML+XML, */ *
2. ใช้ส่วนขยาย
URL เดียวกันนั้นหายไป แต่วิธีนี้ใช้มากที่สุดในสภาพแวดล้อมจริงเพราะมันสอดคล้องกับมุมมองความงามของโปรแกรมเมอร์มากขึ้น
ตัวอย่างเช่น /user.json /user.xls /user.xml
การใช้พารามิเตอร์ตอนนี้ API แบบเปิดจำนวนมากใช้วิธีนี้เช่น Taobao
อย่างไรก็ตามสำหรับเบราว์เซอร์ที่แตกต่างกันการยอมรับหัวอาจไม่ได้รับการรวมเป็นพิเศษดังนั้นการใช้งานจำนวนมากจึงเลือก 2 3 สองวิธีแก้ปัญหา
เราใช้วิธีแก้ปัญหาสองประการข้างต้นในฤดูใบไม้ผลิ
แรกกำหนดค่าการเจรจาต่อรองเนื้อหา
รหัส
@Bean สาธารณะ ViewResolver ContentNegotiatingViewResolver (ContentNegoTiationManager Manager) {// กำหนดมุมมอง ViewVer ViewResolver BeannameViewResolver = ใหม่ BeannameViewResolver (); รายการ <ViewResOlver> Resolver = lists.newarrayList (BeannameViewResolver); ContentNegotiatingViewResolver Resolver = ใหม่ ContentNegotiatingViewResolver (); Resolver.SetViewResolvers (ตัวแก้ไข); Resolver.SetContentNegotiationManager (ผู้จัดการ); กลับมาแก้ไข } @Override โมฆะสาธารณะ configureContentNegotiation (ContentNegotiationConfigurer กำหนดค่า) {configurer.FavorPathExtension (จริง) .usejaf (เท็จ). FavorParameter (จริง). parametername ("รูปแบบ"). .Mediatype ("JSON", MediaType.Application_JSON) .Mediatype ("XLS", Excel_media_type); -สร้างตัวแปลงที่เกี่ยวข้อง
ส่วนตัว httpmessageConverter <Object> createExcelhttpmessageConverter () {excelhttpmessageConverter excelhttpmessageConverter = ใหม่ excelhttpmessageConverter (); ส่งคืน excelhttpmessageconverter; -ข้อมูลส่งออกโดยตรงโดยใช้ Easy-POI
/ * * ลิขสิทธิ์ (c) 2017. Lorem ipsum dolor sit amet, adipiscing elit * Morbi Non Lorem Porttitor Neque Feugiat Blandit UT VITAE IPSUM EGET QUAM LACINIA ACCUMSAN * etiam sed turpis ac ipsum condimentum fringilla Maecenas Magna * proin dapibus sapien vel ante ALIQUAM ERAT VOLUTPAT PELLENTESQUE SAGITTIS LIGULA EGET METUS * ใบพัดขนถ่าย UT RHONCUS GRAVIDA ARCU */ แพ็คเกจ com.f6car.base.web.converter; นำเข้า cn.afterturn.easypoi.excel.excelexportutil; นำเข้า com.f6car.base.common.result; นำเข้า com.f6car.base.core.excelexport; นำเข้า com.f6car.base.core.excelexportparam; นำเข้า com.github.pagehelper.pageInfo; นำเข้า com.google.common.collect.lists; นำเข้า org.apache.poi.ss.usermodel.workbook; นำเข้า org.springframework.http.httpheaders; นำเข้า org.springframework.http.httpinputMessage; นำเข้า org.springframework.http.httpoutputMessage; นำเข้า org.springframework.http.mediatype; นำเข้า org.springframework.http.converter.abstracthttpmessageConverter; นำเข้า org.springframework.http.converter.generichttpmessageConverter; นำเข้า org.springframework.http.converter.httpmessagenotreadableException; นำเข้า org.springframework.http.converter.httpmessagenotwritable Exception; นำเข้า java.io.ioException; นำเข้า java.lang.reflect.type; นำเข้า java.net.urlencoder; นำเข้า Java.util.Collection; นำเข้า Java.util.Collections; นำเข้า Java.util.Collections; นำเข้า java.util.map; นำเข้า com.f6car.base.core.f6static.getexcelexportparam; / ** * @author qixiaObo */ คลาสสาธารณะ Excelhttpmessageconverter ขยาย AbstracthttpmessageConverter <Object> ใช้ GenerichttpMessageConverter <Ojrop> Public ExcelhttpMessageConverter () {super (excel_media_type); } @Override boolean ที่ได้รับการป้องกัน (คลาส <?> clazz) {return false; } @Override วัตถุที่ได้รับการป้องกัน readInternal (คลาส <?> clazz, httpinputMessage inputMessage) พ่น IOException, httpmessagenotreadableException {return null; } @Override Void Void WriteInternal (Object O, HttpOutputMessage outputMessage) พ่น IOException, httpmessagenotwritableException {httpheaders ส่วนหัว = outputMessage.getHeaders (); การรวบรวมข้อมูล = getActualData ((ผลลัพธ์) o); ExcelexportParam excelexportParam = getExcelexportParam (); สมุดงานเวิร์กบุ๊ก; Switch (excelexportParam.getExcelexport ()) {case normalexcel: workbook = excelexportutil.exportexcel (excelexportParam.getExportParams (), (คลาส <?>) excelexportParam.getClazz (), (คอลเลกชัน <?>); หยุดพัก; Case MapExcel: Workbook = Excelexportutil.exportexcel (ExcelexportParam.getExportParams (), ExcelexportParam.getExcelexportentities (), (คอลเลกชัน <? ขยายแผนที่ <?,? >>) ข้อมูล); หยุดพัก; Case BigExcel: Case MapExcelgraph: Case Pdftemplate: Case TemplateExcel: Case Templateword: ค่าเริ่มต้น: โยน runtimeException ใหม่ (); } if (workbook! = null) {if (excelexportParam.getFileName ()! = null) {สตริง codedFileName = urlencoder.encode (excelexportParam.getFileName () Headers.SetContentDispositionFormData ("เอกสารแนบ", codedfilename); } workbook.write (outputMessage.getBody ()); }} คอลเลกชันส่วนตัว getActualData (ผลลัพธ์ r) {ถ้า (r! = null && r.getData ()! = null) {data object = r.getData (); if (data instanceof pageinfo) {return ((pageInfo) ข้อมูล) .getList (); } อื่นถ้า (! (การรวบรวมข้อมูลอินสแตนซ์ของข้อมูล)) {data = lists.newarraylist (ข้อมูล); } else {return (collection) ข้อมูล; }} return collections.empylist (); } @Override บูลีนสาธารณะ canread (ประเภทประเภท, คลาส <?> contextclass, mediaType mediaType) {// excel return false ไม่ได้รับการสนับสนุน; } @Override การอ่านวัตถุสาธารณะ (ประเภทประเภท, คลาส <?> contextclass, httpinputMessage inputMessage) พ่น IOException, httpmessagenotreadableException {return null; } @Override บูลีนสาธารณะ canWrite (ประเภทประเภท, คลาส <?> clazz, mediaType mediaType) {return super.canwrite (mediaType) && clazz == result.class && สนับสนุน (); } การสนับสนุนบูลีนส่วนตัว () {excelexportParam param = getExcelexportParam (); if (param == null || param.getExcelexport () == null || param.getExportParams () == null) {return false; } if (param.getExcelexport () == excelexport.normalexcel) {return true; } else {logger.warn (param.getExcelexport () + "ไม่สนับสนุนตอนนี้!"); กลับเท็จ; }} @Override โมฆะสาธารณะเขียน (Object O, ประเภทประเภท, MediaType ContentType, httpOutputMessage outputMessage) พ่น IOException, httpmessagenotwritable Exception {super.write (o, contentType, outputMessage); -ในขณะนี้มันเป็นเพียงการส่งออกดังนั้นเมื่อใช้ดังนี้
@getMapping @apioperation (value = "รับรายการเอนทิตี", notes = "") รายการผลลัพธ์สาธารณะ (S SO) {pageHelper.startPage (So.getCurrentPage (), so.getPagesize ()); รายการ <v> list = service.findall (); PageInfo PageInfo = ใหม่ PageInfo (รายการ); ExcelexportParam (); Return ResultGenerator.genSuccessResult (PageInfo); } void void excelexportParam () {exportParams ep = exportParams ใหม่ (null, "data"); ExcelexportParam <v> param = ใหม่ excelexportParam <> (); param.setClazz (VOCLAZZ); param.setexcelexport (excelexport.normalexcel); param.setexportparams (EP); param.setFilename ("file.xls"); f6static.setexcelexportparam (param); -เมื่อเราเยี่ยมชม
http://127.0.0.1:8079/zeus/user
{"รหัส": 200, "data": {"endrow": 10, "FirstPage": 1, "HasnextPage": จริง, "HasPreviousPage": FALSE, "ISFIRSTPAGE": TRUE, "ISLASTPAGE": FALSE, "LastPage" 24201883434352650, "idownorg": 2399319937825296, "idrole": 88, "idwxbstation": "332", "idwxbuser": "207", "isadmin": 1, "Isdel": 0, " "", "รหัสผ่าน": "96E79218965EB72C92A549DD5A330112", "PKID": 23993199378825296, "ชื่อผู้ใช้": "IDEMOLEGE": 4, "IDWXBSTATION": "", "", "IDWXBUSER": "", "ISADMIN": 0, "ISDEL": 0, "ISGUIDEOPEN": 0, "LimitMac": 0, "OpenId": "", "96E79218965 24201883434356532, "ชื่อผู้ใช้": "007"}, {"โทรศัพท์มือถือ": "15715139000", "idemployee": 24351585207523460, "idownorg": 242018834343434343434343434343434343434343 "idwxbuser": "298", "isadmin": 1, "isdel": 0, "isguideopen": 0, "LimitMac": 0, "OpenId": "", "รหัสผ่าน": "96E79218965EB72C92A549D5A330112" "ชื่อผู้ใช้": "15715139000"}, {"โทรศัพท์มือถือ": "", "idemployee": 0, "idownorg": 24201883434357600, "idrole": 216, "idwxbstation": "," idwxbuser " 0, "LimitMac": 0, "OpenId": "", "รหัสผ่าน": "96E79218965EB72C92A549DD5A330112", "PKID": 24201883434357920, "username": "Sunlingli" 24351585207425676, "idownorg": 24201883434359384, "idrole": 90, "idwxbstation": "348", "idwxbuser": "227", "isadmin": 1, "Isdel": 0, " "opzuds_v13we500kxymj6xg_gfee", "รหัสผ่าน": "96E79218965EB72C92A549DD5A330112", "PKID": 242018834359388, "USERNAME" "idemployee": 0, "idownorg": 24201883434359790, "idrole": 91, "idwxbstation": "315", "idwxbuser": "175", "isadmin": 1, "isdel": 0, " "96E79218965EB72C92A549DD5A330112", "PKID": 24201883434359790, "ชื่อผู้ใช้": "13809056211" "idownorg": 24201883434359890, "idrole": 92, "idwxbstation": "317", "idwxbuser": "178", "isadmin": 1, "Isdel": 0, "Isguideopen": 0 " "96E79218965EB72C92A549DD5A330112", "PKID": 24201883434359892, "ชื่อผู้ใช้": "18903885585"}, {"มือถือ": "" 24201883434359924, "idrole": 93, "idwxbstation": "318", "idwxbuser": "179", "isadmin": 1, "Isdel": 0, "Isguideopen": 0, "LimitMac": 0, " "96E79218965EB72C92A549DD5A330112", "PKID": 24201883434359930, "ชื่อผู้ใช้": "13372299595"}, {"มือถือ": "" "idrole": 94, "idwxbstation": "321", "idwxbuser": "188", "isadmin": 1, "isdel": 0, "isguideopen": 0, "Limitmac": 0, "OpenId": "", " "pkid": 24201883434360052, "ชื่อผู้ใช้": "15221250005"}, {"โทรศัพท์มือถือ": "", "idemployee": 0, "Idownorg": 24201883434360070 " "Isadmin": 1, "Isdel": 0, "Isguideopen": 0, "LimitMac": 0, "OpenId": "", "รหัสผ่าน": "96E79218965EB72C92A549DD5A330112" }], "NavigateFirstPage": 1, "NavigatelastPage": 8, "NaviGatePages": 8, "Naviterpagenums": [1, 2, 3, 4, 5, 6, 7, 8], "NextPage": 2, "", "10:" 10: "10: "Startrow": 1, "Total": 1012}, "Message": "Success"}เมื่อเข้าถึง http://127.0.0.1:8079/zeus/user?format=xls หรือ http://127.0.0.1:8079/zeus/user.xls
เอฟเฟกต์ต่อไปนี้
เนื่องจากข้อมูลที่นี่เกี่ยวข้องกับการสืบค้นเราจึงสามารถใช้งานได้ด้วยวิธีนี้ http://127.0.0.1:8079/zeus/user.xls?pagesize=1000 ตระหนักถึง XLSization ของผลลัพธ์การสืบค้นได้อย่างง่ายดาย!
สรุป
ข้างต้นเป็นภาพประกอบของผู้เจรจาต่อรองเนื้อหาใน Springboot ที่แนะนำโดยบรรณาธิการ ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับคุณทันเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!