บทนำบริการพักผ่อน
Restful Service เป็นรูปแบบสถาปัตยกรรมที่ได้รับความนิยมมากขึ้นในช่วงไม่กี่ปีที่ผ่านมา บริการเว็บที่มีน้ำหนักเบาเล่นได้รับการโพสต์และลบโพรโทคอล HTTP เมื่อเปรียบเทียบกับ SOAP ที่ซับซ้อนและ XML-RPC บริการเว็บของ REST Mode นั้นมีความรัดกุมมากขึ้นและบริการเว็บมากขึ้นเรื่อย ๆ ก็เริ่มที่จะนำการออกแบบและการใช้งานสไตล์ REST มาใช้ ตัวอย่างเช่น Amazon.com ให้บริการเว็บที่ใกล้เคียงกับสไตล์ REST สำหรับการค้นหาหนังสือ บริการเว็บที่จัดทำโดย Yahoo ก็เป็นสไตล์ที่เหลือเช่นกัน ส่วนที่เหลือไม่ใช่ตัวเลือกที่เหมาะสมเสมอไป มันได้รับความนิยมในฐานะวิธีการออกแบบบริการเว็บที่พึ่งพามิดเดิลแวร์ที่เป็นกรรมสิทธิ์น้อยกว่าเช่นแอปพลิเคชันเซิร์ฟเวอร์มากกว่าวิธีการที่ใช้ SOAP และ WSDL ในแง่หนึ่งโดยเน้นมาตรฐานอินเทอร์เน็ตในช่วงต้นเช่น URI และ HTTP REST เป็นการถดถอยของเว็บแนวทางก่อนยุคของเซิร์ฟเวอร์แอปพลิเคชันขนาดใหญ่
ตัวอย่างดังที่แสดงในรูปต่อไปนี้:
กุญแจสำคัญในการใช้ REST คือวิธีการเป็นนามธรรมทรัพยากร ยิ่งนามธรรมที่แม่นยำยิ่งขึ้นก็ยิ่งแอปพลิเคชันส่วนที่เหลือดีขึ้นเท่านั้น
หลักการสำคัญของการบริการ REST:
1. ให้ id วัตถุทั้งหมด
2. เชื่อมต่อวัตถุเข้าด้วยกัน
3. ใช้วิธีมาตรฐาน
4. การเป็นตัวแทนของทรัพยากรหลายอย่าง
5. การสื่อสารไร้สัญชาติ
บทความนี้แนะนำวิธีการสร้างกรอบบริการ REST อย่างง่ายตามการบูตฤดูใบไม้ผลิและวิธีการใช้การรับรองความถูกต้องของบริการ REST ผ่านคำอธิบายประกอบที่กำหนดเอง
สร้างกรอบ
pom.xml
ขั้นแรกแนะนำการพึ่งพาที่เกี่ยวข้องใช้ MongoDB สำหรับฐานข้อมูลและใช้ REDIS สำหรับแคช
หมายเหตุ: ไม่มีการใช้ Tomcat ที่นี่ แต่ undertow
<การพึ่งพา> <roupId> org.springframework.boot </groupId> <ratifactid> Spring-Boot-Starter </artifactid> </การพึ่งพา> <การพึ่งพาอาศัย> <roupid> org.springframework.boot </groupid> <RoupID> org.springframework.boot </groupId> <ratifactid> Spring-Boot-Starter-Web </artifactid> <epervusions> <exclusion> <springId> org.springframework.boot </groupid> <การพึ่งพา> <roupId> org.springframework.boot </groupId> <ratifactid> Spring-Boot-Starter-Undertow </artifactid> </dermentrency> <! </permentency> <!-การสนับสนุน MongoDB-> <การพึ่งพา> <roupId> org.springframework.boot </groupId> <ratifactid> Spring-Boot-Starter-Data-MongoDB </artifactid>
แนะนำบริการเว็บสนับสนุน Spring-Boot-Starter-Web
การแนะนำ Spring-Boot-Starter-Data-Redis และ Spring-Boot-Starter-Data-MongoDB สามารถใช้ MongoDB และ Redis ได้อย่างง่ายดาย
ไฟล์กำหนดค่า
ฟังก์ชันโปรไฟล์
เพื่ออำนวยความสะดวกความแตกต่างระหว่างสภาพแวดล้อมการพัฒนาและสภาพแวดล้อมออนไลน์ฟังก์ชันโปรไฟล์สามารถใช้เพื่อเพิ่มในแอปพลิเคชัน properties
spring.profiles.active=dev
จากนั้นเพิ่ม Application-dev.properties เป็นไฟล์กำหนดค่า dev
การกำหนดค่า mondb
เพียงกำหนดค่าที่อยู่ฐานข้อมูล
Spring.data.mongoDb.uri = mongoDb: // ip: พอร์ต/ฐานข้อมูล? readpreference = PrimaryPreferred
การกำหนดค่า Redis
Spring.redis.database = 0 # ที่อยู่เซิร์ฟเวอร์ REDIS SPRING.REDIS.HOST = IP # REDIS SERVER การเชื่อมต่อพอร์ตสปริง REDIS.port = 6379 # รหัสผ่านการเชื่อมต่อเซิร์ฟเวอร์เซิร์ฟเวอร์ REDIS (ค่าเริ่มต้นว่างเปล่า) Spring.Redis.Password = # จำนวนสูงสุดของการเชื่อมต่อการเชื่อมต่อ Spring.redis.pool.max-wait = -1 # การเชื่อมต่อที่ไม่ได้ใช้งานสูงสุดในการเชื่อมต่อพูลสปริงเรดริส.
การเข้าถึงข้อมูล
mongdb
การเข้าถึง MongDB นั้นง่ายมาก คุณสามารถกำหนดอินเทอร์เฟซขยายได้โดยตรง นอกจากนี้ยังสามารถรองรับไวยากรณ์ JPA ได้เช่น:
@ComponentPublic Interface UserRepository ขยาย MongorePository <ผู้ใช้จำนวนเต็ม> {ผู้ใช้สาธารณะ findByUserName (ชื่อผู้ใช้สตริง);}เมื่อใช้งานเพียงเพิ่มคำอธิบายประกอบ @autowired
@componentpublic คลาส Authservice ขยาย Baseservice {@autowired UserRepository UserRepository; -การเข้าถึง REDIS
ใช้ Stringredistemplate เพื่อเข้าถึง REDIs โดยตรง
@componentpublic คลาส Baseservice {@autowired Mongotemplate Mongotemplate; @autowired Protected Stringredistemplate Stringredistemplate; -จัดเก็บข้อมูล:
.StringRedistemplate.OpsForValue (). set (token_key, user.getId ()+"", token_max_age, timeunit.seconds);
ลบข้อมูล:
Stringredistemplate.delete (getFormattoken (AccessToken, แพลตฟอร์ม));
บริการเว็บ
กำหนดคลาสคอนโทรลเลอร์เพิ่ม RestController และใช้ requestmapping เพื่อตั้งค่าเส้นทาง URL
@RestControllerPublic คลาส AuthController ขยาย basecontroller {@requestmapping (value = {"/"}, ผลิต = "แอปพลิเคชัน/json; charset = utf-8", method = {requestmethod.get -ตอนนี้เริ่มต้นคุณควรจะได้เห็น Hello World! ของมัน
การรับรองความถูกต้องของบริการ
กลไกการเข้าถึงแบบง่าย ๆ
ให้อินเทอร์เฟซเข้าสู่ระบบ หลังจากการรับรองความถูกต้องสำเร็จแล้วจะมีการสร้าง AccessToken เมื่อเข้าถึงอินเทอร์เฟซในอนาคต AccessToken จะถูกนำมาด้วย เซิร์ฟเวอร์ใช้ AccessToken เพื่อตรวจสอบว่าเป็นผู้ใช้ตามกฎหมายหรือไม่
เพื่อความสะดวกคุณสามารถบันทึก AccessToken เป็น Redis และตั้งค่าระยะเวลาที่ถูกต้อง
String token = encryptionutils.sha256hex (string.format ("%s%s", user.getUserName (), system.currentTimeMillis ())); String token_key = getFormattoken (โทเค็น, แพลตฟอร์ม); this.stringredistemplate.opsforvalue (). set (token_key, user.getId ()+"", token_max_age, timeunit.seconds);การรับรองความถูกต้องของตัวตน
เพื่ออำนวยความสะดวกในการตรวจสอบตัวตนแบบครบวงจรตัวดักจับสามารถสร้างขึ้นบนพื้นฐานของกลไกการดักจับของสปริงเพื่อดำเนินการตรวจสอบความถูกต้องแบบครบวงจร
AuthCheckInterceptor คลาสสาธารณะใช้ HandlerInterceptor {}เพื่อให้การสกัดกั้นมีผลบังคับใช้อีกขั้นหนึ่งจำเป็นต้องเพิ่มการกำหนดค่า:
@ConfigurationPublic คลาสเซสชันการกำหนดค่าขยาย WebMVCCONFigurerAdapter {@AutoWired AuthCheckInterceptor AuthCheckInterceptor; @Override โมฆะสาธารณะ AddInterceptors (InterceptorRegistry Registry) {super.addinterceptors (รีจิสทรี); // เพิ่ม Interceptor registry.addinterceptor (AuthCheckInterceptor) .AddPathPatterns ("/**"); -คำอธิบายประกอบการรับรองความถูกต้องที่กำหนดเอง
เพื่อปรับแต่งการรับรองความถูกต้องของการอนุญาตตัวอย่างเช่นอินเทอร์เฟซบางอย่างสามารถเข้าถึงได้โดยผู้ที่มีสิทธิ์เฉพาะและสามารถแก้ไขได้อย่างง่ายดายผ่านคำอธิบายประกอบที่กำหนดเอง ในคำอธิบายประกอบที่กำหนดเองเพียงเพิ่มบทบาท
/*** คำอธิบายประกอบการตรวจสอบสิทธิ์*/@Target (ElementType.method) @retention (RetentionPolicy.runtime) @DocumentedPublic @Interface AuthCheck {/*** รายการบทบาท* @return*/string [] roles () ค่าเริ่มต้น {};};};};};};};ตรรกะการตรวจสอบ:
ตราบใดที่อินเทอร์เฟซถูกเพิ่มด้วยคำอธิบายประกอบ AuthCheck จะต้องเป็นผู้ใช้ที่เข้าสู่ระบบ
หากมีการระบุบทบาทนอกเหนือจากการเข้าสู่ระบบผู้ใช้ควรมีบทบาทที่สอดคล้องกัน
String [] engentoreUrls = สตริงใหม่ [] {"/user/.*", "/cat/.*", "/app/.*", "/ข้อผิดพลาด"}; บูลีนสาธารณะ prehandle (httpservletrequest httpservletrequest, httpservletResponse httpservletResponse, ตัวจัดการวัตถุ) โยนข้อยกเว้น {// 0 ยืนยันพารามิเตอร์สาธารณะถ้า (! checkParams ("แพลตฟอร์ม" } // 1. ละเว้น url url url การตรวจสอบ url = httpservletrequest.getRequesturi (). toString (); สำหรับ (สตริงที่ไม่สนใจ: ละเว้น) {if (url.matches (ละเว้น)) {return true; }} // 2. คำอธิบายประกอบการตรวจสอบคำอธิบายการสอบถามข้อมูล handlermethod handlermethod = (handlermethod) handler; วิธีการ = handlermethod.getMethod (); // การสืบค้นคำอธิบายประกอบ AuthCheck AuthCheck = method.getNanotation (AuthCheck.class); if (authCheck == null) {// ไม่มีคำอธิบายประกอบไม่มีการส่งคืนจริง; } // 3. หากมีคำอธิบายประกอบให้ตรวจสอบ AccessToken ก่อนถ้า (! CheckParams ("AccessToken", httpservletRequest, httpservletResponse)) {return false; } // ตรวจสอบว่าโทเค็นจะหมดอายุจำนวนเต็ม userId = AuthService.getUserIdFromToken (httpservletRequest.getParameter ("AccessToken"), httpservletRequest.getParameter ("แพลตฟอร์ม")); if (userId == null) {logger.debug ("AccessToken") หมดเวลา "); เอาต์พุต (ResponseResult.builder.error (" AccessToken Expired "). สร้าง (), httpservletResponse); if (authcheck.roles ()! = null && authcheck.roles (). ความยาว> 0) {ผู้ใช้ = AuthService.getUser (userId); การจับคู่การตรวจสอบล้มเหลวถ้า (! ismatch) {return false; การห่อหุ้มผลการตอบสนองบริการ
เพิ่มตัวสร้างเพื่ออำนวยความสะดวกในการสร้างผลลัพธ์สุดท้าย
การตอบสนองระดับสาธารณะ {ตัวสร้างคลาสคงที่สาธารณะ {responseresult responseresult; แผนที่ <สตริงวัตถุ> datamap = maps.newhashmap (); Public Builder () {this.responseresult = new ResponserEsult (); } Builder สาธารณะ (สถานะสตริง) {this.responseresult = new ResponseResult (สถานะ); } Public Static Builder newBuilder () {return New Builder (); } ความสำเร็จของผู้สร้างแบบคงที่สาธารณะ () {ส่งคืนผู้สร้างใหม่ ("ความสำเร็จ"); } ข้อผิดพลาดของตัวสร้างแบบคงที่สาธารณะ (ข้อความสตริง) {builder builder = ใหม่ builder ("ข้อผิดพลาด"); builder.responseresult.setError (ข้อความ); Builder return; } ภาคผนวกตัวสร้างสาธารณะ (คีย์สตริง, ข้อมูลวัตถุ) {this.datamap.put (คีย์, ข้อมูล); คืนสิ่งนี้; } / *** ตั้งค่าข้อมูลรายการ* @param Data Data* @return* / Public Builder SetlistData (รายการ <?> data) {this.datamap.put ("ผลลัพธ์", data); this.datamap.put ("รวม", dataS.size ()); คืนสิ่งนี้; } ผู้สร้างสาธารณะ setData (ข้อมูลวัตถุ) {this.datamap.clear (); this.responseresult.setData (ข้อมูล); คืนสิ่งนี้; } บูลีน wrapData = false; / ** * ห่อข้อมูลในข้อมูล * @param wrapdata * @return */ public builder wrap (boolean wrapdata) {this.wrapdata = wrapdata; คืนสิ่งนี้; } public String build () {jsonObject jsonObject = new jsonObject (); jsonObject.put ("state", this.responseresult.getState ()); if (this.responseresult.getState (). เท่ากับ ("ข้อผิดพลาด")) {jsonObject.put ("ข้อผิดพลาด", this.responseresult.getError ()); } if (this.responseresult.getData ()! = null) {jsonobject.put ("data", json.tojson (this.responseresult.getData ()); } อื่นถ้า (datamap.size ()> 0) {ถ้า (wrapdata) {jsonObject data = new JsonObject (); datamap.foreach ((คีย์, ค่า) -> {data.put (คีย์, ค่า);}); jsonObject.put ("ข้อมูล", ข้อมูล); } else {datamap.foreach ((คีย์, ค่า) -> {jsonobject.put (คีย์, ค่า);}); }} return jsonobject.tojsonstring (); }} สถานะสตริงส่วนตัว; ข้อมูลวัตถุส่วนตัว ข้อผิดพลาดสตริงส่วนตัว สตริงสาธารณะ getError () {return error; } โมฆะสาธารณะ setError (ข้อผิดพลาดสตริง) {this.error = ข้อผิดพลาด; } การตอบสนองสาธารณะ () {} การตอบสนองสาธารณะ (สตริง rc) {this.state = rc; } / ** * ส่งคืนเมื่อประสบความสำเร็จ * @param rc * @param ผลลัพธ์ * / การตอบสนองสาธารณะ (สตริง rc, ผลลัพธ์วัตถุ) {this.state = rc; this.data = ผลลัพธ์; } สตริงสาธารณะ getState () {return state; } โมฆะสาธารณะ setState (สถานะสตริง) {this.state = state; } วัตถุสาธารณะ getData () {ส่งคืนข้อมูล; } โมฆะสาธารณะ setData (ข้อมูลวัตถุ) {this.data = ข้อมูล; - สง่างามมากขึ้นเมื่อโทร
@RequestMapping (value = {"/ผู้ใช้/เข้าสู่ระบบ", "/pc/user/login"}, ผลิต = "แอปพลิเคชัน/json; charset = utf-8", method = {requestMethod.get, requestMethod.post}) @ResponseBody String String if (user! = null) {// เข้าสู่ระบบไปยัง String token = AuthService.upDatetoken (ผู้ใช้, แพลตฟอร์ม); return responseresult.builder .success () .append ("AccessToken", โทเค็น) .append ("userId", user.getId ()) .build (); } return responseResult.builder.error ("ผู้ใช้ไม่มีอยู่หรือรหัสผ่านผิด"). build (); } ข้อผิดพลาดสตริงที่ได้รับการป้องกัน (ข้อความสตริง) {return responseResult.builder.error (ข้อความ) .build (); } ความสำเร็จของสตริงที่ได้รับการป้องกัน () {return responseresult.builder .success () .build (); } String SuccessDatalist (รายการ <?> data) {return responseResult.builder .success () .wrap (จริง) // data package.setListData (ข้อมูล) .build (); -สรุป
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่าเนื้อหาของบทความนี้จะมีค่าอ้างอิงบางอย่างสำหรับการศึกษาหรือที่ทำงานของทุกคน หากคุณมีคำถามใด ๆ คุณสามารถฝากข้อความไว้เพื่อสื่อสาร ขอบคุณสำหรับการสนับสนุน Wulin.com