บทความนี้แนะนำการใช้งานไคลเอนต์ Jersey เพื่อขอบริการ Spring Boot (resful) และแบ่งปันกับคุณดังนี้:
ไคลเอนต์ Jersey ได้รับการห่อหุ้มอินสแตนซ์ของวัตถุไคลเอนต์:
@Service ("JerseypoolingClient") คลาสสาธารณะ JerseypoolingClientFactoryBean ใช้ FactoryBean <client>, InitializingBean, disposableBean { /*** อินเทอร์เฟซไคลเอ็นต์เป็นอินเทอร์เฟซพื้นฐานของไคลเอนต์ที่เหลือและใช้ในการสื่อสารกับเซิร์ฟเวอร์ที่เหลือ ลูกค้าถูกกำหนดให้เป็นวัตถุเฮฟวี่เวทที่จัดการวัตถุต่าง ๆ ที่ด้านล่างของการสื่อสารของลูกค้าเช่นตัวเชื่อมต่อตัวแยกวิเคราะห์ ฯลฯ ดังนั้นจึงไม่แนะนำให้สร้างอินสแตนซ์ไคลเอนต์จำนวนมากในแอปพลิเคชัน สิ่งนี้จำเป็นในการพัฒนา นอกจากนี้อินเทอร์เฟซนี้ต้องการให้อินสแตนซ์จะต้องปิดมิฉะนั้นจะทำให้หน่วยความจำรั่วไหล*/ ไคลเอนต์ไคลเอนต์ส่วนตัว; / ** * จำนวนการเชื่อมต่อสูงสุดสำหรับไคลเอนต์, ค่าเริ่มต้นคือ 2000 */ ส่วนตัว int maxtotal = 2000; / *** จำนวนการเชื่อมต่อสูงสุดเริ่มต้นต่อเส้นทาง*/ ส่วนตัว int defaultMaxperRoute = 1000; clientConfig ส่วนตัว clientConfig; สาธารณะ jerseypoolingClientFactoryBean () {} / *** ตัวสร้างที่มีการกำหนดค่า* @param clientConfig* / สาธารณะ jerseypoolingClientFactoryBean (clientConfig clientConfig) {this.ClientConfig = clientConfig; } สาธารณะ JerseypoolingClientFactoryBean (int maxtotal, int defaultMaxperRoute) {this.maxtotal = maxtotal; this.defaultMaxperRoute = defaultMaxperRoute; } / ** * ความสนใจ: * รายละเอียด: การปล่อยทรัพยากรลูกค้าเมื่อคอนเทนเนอร์ถูกทำลาย * @author chhliu * / @Override โมฆะสาธารณะทำลาย () โยนข้อยกเว้น {this.client.close (); } / ** * * ความสนใจ: * รายละเอียด: เริ่มต้นวัตถุไคลเอนต์ในรูปแบบของพูลการเชื่อมต่อ * @author chhliu * / @Override โมฆะสาธารณะ Afterpropertiesset () พ่นข้อยกเว้น {// ถ้าตัวสร้างที่มี clientconfig ไม่ได้ใช้งาน NULFINED clientConfig (); // อินสแตนซ์การจัดการพูลการเชื่อมต่อคลาสนี้มีความปลอดภัยจากเธรดและรองรับการดำเนินการที่เกิดขึ้นพร้อมกันหลายรายการที่เกิดขึ้นพร้อมกัน pcm.setmaxtotal (this.maxtotal); PCM.SetDefaultMaxperRoute (this.defaultMaxperRoute); clientConfig.Property (ApacheClientProperties.Connection_Manager, PCM); / * * เมื่อใช้ Jersey เพื่อขอบริการ Boot Spring Spring Boot ใช้ Jackson เพื่อแยก JSON โดยค่าเริ่มต้น * ในขณะที่ Jersey ใช้ Moxy เพื่อแยก JSON โดยค่าเริ่มต้น เมื่อไคลเอนต์ Jersey ต้องการให้บริการ Spring Boot เพื่อขอทรัพยากร* ความแตกต่างนี้จะทำให้เซิร์ฟเวอร์และไคลเอนต์แปลง POJO แตกต่างกันส่งผลให้เกิดข้อผิดพลาด deserialization* ดังนั้นคุณต้องลงทะเบียนคุณสมบัติ Jackson ในอินสแตนซ์การกำหนดค่าของลูกค้าที่นี่*/ clientConfig.register (JacksonFeature.class) // ใช้ตัวเชื่อมต่อการกำหนดค่า Apache ตัวเชื่อมต่อเริ่มต้นคือ httpurlconnector clientconfig.connectorprovider (ใหม่ apacheconnectorprovider ()); client = clientBuilder.NewClient (clientConfig); } else {// ใช้ clientConfig ในคอนสตรัคเตอร์เพื่อเริ่มต้นวัตถุไคลเอนต์ client = clientBuilder.NewClient (this.ClientConfig); }} /** * ความสนใจ: * รายละเอียด: ส่งคืนวัตถุไคลเอนต์ หากวัตถุเป็นโมฆะให้สร้างไคลเอนต์เริ่มต้น * @author chhliu */ @Override ไคลเอนต์สาธารณะ getObject () พ่นข้อยกเว้น {ถ้า (null == this.client) {ส่งคืน clientBuilder.newClient (); } ส่งคืนสิ่งนี้ client; } / ** * ความสนใจ: * รายละเอียด: รับประเภทของวัตถุลูกค้า * @author chhliu * / @Override คลาสสาธารณะ <?> getObjectType () {return (this.client == null? client.class: this.client.getClass ()); } / ** * ความสนใจ: * รายละเอียด: ไม่ว่าวัตถุไคลเอนต์จะเป็นซิงเกิลตันหรือไม่ที่จะเริ่มต้นเป็นซิงเกิล * @author chhliu * / @Override บูลีน Public Boolean Issingleton () {return true; -การร้องขอการห่อหุ้มของ Spring Boot Service:
@Component ("jerseyclient") คลาสสาธารณะ jerseyclient {@Resource (name = "JerseyPoolingClient") ไคลเอนต์ส่วนตัว; /** * ความสนใจ: * รายละเอียด: สอบถามวัตถุผ่าน id * @author chhliu */public resultmsg <gitHubentity> getResponseById (id สตริงสุดท้าย) พ่น jsonprocessingException, ioexception {webtarget webtarget = client.target ("http: // Invocation.builder InvocationBuilder = WebTarget.Request (MediaType.Application_JSON); generictype <resultmsg <gitHubentity>> genericType = ใหม่ genictype <resultmsg <gitHubentity>> () {}; การตอบสนองการตอบสนอง = InvocationBuilder.get (); ถ้า (response.getStatus () == 200) { /** เมื่อมีการเรียกวิธีการอ่านโปรแกรมจะปล่อยการเชื่อมต่อโดยอัตโนมัติ* แม้ว่าวิธีการอ่านจะไม่ถูกเรียกและวัตถุประเภททั่วไปจะถูกส่งกลับโดยตรง } else {resultmsg <gitHubentity> res = new resultmsg <gitHubentity> (); res.seterRorCode (string.valueof (response.getStatus ())); res.seterrormsg (response.getStatusInfo (). toString ()); res.setok (เท็จ); Ret Res; }} / ** * ความสนใจ: * รายละเอียด: การสืบค้นการแบ่งหน้า * @author chhliu * / public resultmsg <pager <gitHubentity>> getGithubwithPager (ขั้นสุดท้าย pageoffset, หน้าจำนวนเต็มสุดท้าย, สตริงสุดท้าย client.target ("http: // localhost: 8080") .path ("/github/get/users/page") .queryparam ("pageoffset", pageoffset) .queryparam ("pagesize", pagesize) .queryparam ("ordercolumn" // โปรดทราบว่าหากประเภทสื่อที่นี่คือ mediaType.application_json ดังนั้นพารามิเตอร์ที่สอดคล้องกันในบริการจะต้องนำหน้าโดย @requestbody Invocation.builder InvocationBuilder = WebTarget.request (mediaType.application_json); generictype <resultmsg <pager <gitHubentity>>>> genericType = new GenericType <resultmsg <pager <gitHubentity>>> () {}; การตอบสนองการตอบสนอง = InvocationBuilder.get (); if (response.getStatus () == 200) {return response.ReadEntity (generictype); } else {resultmsg <pager <githubentity>> res = new resultmsg <pager <gitHubentity>> (); res.seterRorCode (string.valueof (response.getStatus ())); res.seterrormsg (response.getStatusInfo (). toString ()); res.setok (เท็จ); Ret Res; }} / ** * ความสนใจ: * รายละเอียด: แบบสอบถามตามชื่อผู้ใช้ * @author chhliu * / public resultmsg <list <gitHubentity>> getResponseByEnsername (ชื่อผู้ใช้สตริงสุดท้าย) โยน jsonProcessingException client.target ("http: // localhost: 8080") .path ("/github/get/users/"+ชื่อผู้ใช้); Invocation.builder InvocationBuilder = WebTarget.Request (MediaType.Application_JSON); generictype <resultmsg <list <gitHubentity>> genericType = new GenericType <resultmsg <list <gitHubentity>>> () {}; การตอบสนองการตอบสนอง = InvocationBuilder.get (); if (response.getStatus () == 200) {return response.ReadEntity (generictype); } else {resultmsg <list <githubentity>> res = new resultmsg <list <gitHubentity>> (); res.seterRorCode (string.valueof (response.getStatus ())); res.seterrormsg (response.getStatusInfo (). toString ()); res.setok (เท็จ); Ret Res; }}/** * ความสนใจ: * รายละเอียด: ลบบันทึกตาม ID * @author chhliu */public resultmsg <githubentity> deleteById (id สตริงสุดท้าย) พ่น jsonprocessingException, iOexception {webtarget target = client.target generictype <resultmsg <gitHubentity>> genericType = ใหม่ genictype <resultmsg <gitHubentity>> () {}; การตอบสนองการตอบสนอง = target.request (). ลบ (); if (response.getStatus () == 200) {return response.ReadEntity (generictype); } else {resultmsg <gitHubentity> res = new resultmsg <gitHubentity> (); res.seterRorCode (string.valueof (response.getStatus ())); res.seterrormsg (response.getStatusInfo (). toString ()); res.setok (เท็จ); Ret Res; }}/** * ความสนใจ: * รายละเอียด: อัปเดตบันทึก * @author chhliu */public resultmsg <GitHubentity> อัปเดต (เอนทิตี gitHubentity สุดท้าย) พ่น JsonProcessingException, iOException {webtarget target = client.target generictype <resultmsg <gitHubentity>> genericType = ใหม่ genictype <resultmsg <gitHubentity>> () {}; การตอบสนองการตอบสนอง = target.request (). buildput (entity.Entity (เอนทิตี, mediaType.application_json)). เรียกใช้ (); if (response.getStatus () == 200) {return response.ReadEntity (generictype); } else {resultmsg <gitHubentity> res = new resultmsg <gitHubentity> (); res.seterRorCode (string.valueof (response.getStatus ())); res.seterrormsg (response.getStatusInfo (). toString ()); res.setok (เท็จ); Ret Res; }}/** * ความสนใจ: * รายละเอียด: แทรกบันทึก * @author chhliu */public resultmsg <GitHubentity> บันทึก (เอนทิตี gitHubentity สุดท้าย) พ่น JsonProcessingException, iOException generictype <resultmsg <gitHubentity>> genericType = ใหม่ genictype <resultmsg <gitHubentity>> () {}; การตอบสนองการตอบสนอง = target.request (). buildpost (entity.entity (เอนทิตี, mediaType.application_json)). เรียกใช้ (); if (response.getStatus () == 200) {return response.ReadEntity (generictype); } else {resultmsg <gitHubentity> res = new resultmsg <gitHubentity> (); res.seterRorCode (string.valueof (response.getStatus ())); res.seterrormsg (response.getStatusInfo (). toString ()); res.setok (เท็จ); Ret Res; - คำอธิบายโดยละเอียดเกี่ยวกับอินเทอร์เฟซไคลเอนต์ Jersey
1 อินเทอร์เฟซไคลเอ็นต์
การสร้างอินสแตนซ์ไคลเอนต์ถูกสร้างขึ้นผ่าน ClientBuilder โดยปกติแล้วอินสแตนซ์ clientConfig จะใช้เป็นพารามิเตอร์ หากเราใช้ client client = clientBuilder.newClient () เพื่อสร้างอินสแตนซ์ไคลเอนต์เราจะสร้างอินสแตนซ์ไคลเอนต์ทุกครั้ง แต่อินสแตนซ์เป็นวัตถุเฮฟวี่เวท ดังนั้นจึงขอแนะนำให้ใช้การเชื่อมต่อการเชื่อมต่อ HTTP เพื่อจัดการการเชื่อมต่อแทนที่จะสร้างวัตถุไคลเอนต์ทุกครั้งที่เราร้องขอ สำหรับวิธีการจัดการพูลการเชื่อมต่อที่เฉพาะเจาะจงดูตัวอย่างรหัสด้านบน
2 อินเตอร์เฟส WebTarget
อินเทอร์เฟซ WebTarget เป็นอินเทอร์เฟซที่ใช้การวางตำแหน่งทรัพยากรสำหรับไคลเอนต์ REST ผ่านอินเทอร์เฟซ WebTarget เราสามารถกำหนดที่อยู่เฉพาะของทรัพยากรที่ร้องขอพารามิเตอร์การสืบค้นและข้อมูลประเภทสื่อ ฯลฯ เราสามารถดำเนินการกำหนดค่าของอินสแตนซ์ WebTarget ผ่านห่วงโซ่วิธีการ แต่ควรสังเกตว่าแม้ว่าวิธีการใช้งานของ WebTarget นั้นคล้ายกับวิธีการของ StringBuffer ห่วงโซ่วิธีการของ WebTarget จะต้องตั้งค่าการส่งคืนของวิธีการเป็นที่จับไปยังกระบวนการที่ตามมา สิ่งนี้หมายความว่าอย่างไร? ดูตัวอย่างต่อไปนี้:
ตัวอย่างที่ 1: ตัวอย่างเมธอด StringBuffer
StringBuffer SB = ใหม่ StringBuffer ("LCH"); sb.append ("สวัสดี"); sb.append ("โลก"); sb.append ("สวัสดี") ผนวก ("โลก"); // วิธีนี้เหมือนกับรหัสสองบรรทัดข้างต้นตัวอย่างที่ 2: ตัวอย่างเมธอด WebTarget
// ใช้ห่วงโซ่วิธีรหัสหนึ่งบรรทัดเพื่อยกตัวอย่าง WebTarget WebTarget WebTarget = client.target ("http: // localhost: 8080"); webtarget.path ("/github/get/users/page") .queryparam ("pageoffset", pageoffset) .queryparam ("pagesize", pagesize) .QueryParam ("OrderColumn", OrderColumn); // นี่คือการใช้เมธอดโซ่เพื่อสร้างอินสแตนซ์ WebTarget WebTarget.Path ("/gitHub/get/users/page"); webtarget.queryparam ("pageoffset", pageoffset); WebTarget.QueryParam ("PAGESIZE", PAGESIZE); // ผลลัพธ์ของวิธีการอินสแตนซ์สองวิธีข้างต้นนั้นแตกต่างกันมาก วิธีการสร้างอินสแตนซ์ข้างต้นไม่เป็นไรไม่มีปัญหา แต่วิธีการสร้างอินสแตนซ์ต่อไปนี้มีปัญหา ในวิธีการสร้างอินสแตนซ์ต่อไปนี้แต่ละแถวจะสร้างวัตถุ A // ใหม่ของ WebTarget WebTarget ดั้งเดิมไม่ได้มีบทบาทใด ๆ ท้ายที่สุดอินสแตนซ์ของแต่ละแถวจะแตกต่างกัน หากเราต้องการสร้างอินสแตนซ์ในหลายแถวเราจะต้องให้การจัดการสำหรับการกลับมาของแต่ละวิธี วิธีการดังต่อไปนี้: เป้าหมาย WebTarget = client.target ("http: // localhost: 8080"); webtarget pathtarget = target.path ("/github/get/users/page"); webtarget paramtarget = pathtarget.queryparam ("pageoffset", pageoffset); // เมื่อใช้งานล่าสุดให้ใช้วัตถุอินสแตนซ์ WebTarget ล่าสุด 3 อินเทอร์เฟซการเรียกร้อง
อินเทอร์เฟซการเรียกใช้เป็นอินเทอร์เฟซที่เริ่มการร้องขอไปยังเซิร์ฟเวอร์ REST หลังจากเสร็จสิ้นการกำหนดค่าการวางตำแหน่งทรัพยากร คำขอประกอบด้วยสองวิธี: การซิงโครไนซ์และอะซิงโครนัส มันถูกกำหนดโดยอินเทอร์เฟซตัวสร้างภายในอินเตอร์เฟสการเรียกร้อง อินเทอร์เฟซตัวสร้างสืบทอดการซิงโครไนซ์อินเตอร์เฟสการซิงโครไนซ์ ตัวอย่างของการโทรแบบอะซิงโครนัสมีดังนี้:
Future <resultmsg <list <gitHubentity>> การตอบสนอง = InvocationBuilder.async (). รับ (genictype); if (response.isdone ()) {return response.get (); - อินสแตนซ์อินเทอร์เฟซ builder จะเรียกใช้งาน GET และ Post Requests เพื่อส่งแบบสอบถามและสร้างตามลำดับ โดยค่าเริ่มต้นประเภทการส่งคืนของวิธีการ HTTP คือประเภทการตอบสนองและยังรองรับค่าส่งคืนของประเภททั่วไป ในตัวอย่างข้างต้นเราใช้ยาสามัญจำนวนมากดังนั้นเราจะไม่อธิบายมากเกินไปที่นี่
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น