ในระหว่างกระบวนการพัฒนาเว็บ Java จะมีข้อยกเว้นระบบหรือข้อยกเว้นเทียมอย่างหลีกเลี่ยงไม่ได้ วิธีจัดการกับมันอย่างสง่างามในโครงการสปริงบู๊ตพักผ่อน?
การวิเคราะห์: ในโครงการ Springboot สไตล์พักผ่อนวัตถุที่ส่งคืนเป็นวัตถุร่างกายทั้งหมดดังนั้นจึงเหมาะสมกว่าที่จะกำหนดคลาสฐานผลลัพธ์ที่มีสถานะข้อความข้อมูล (ผลตอบแทนของวิธีการร้องขอ)
มันจะลำบากมากขึ้นถ้าคุณกำหนดคลาสข้อยกเว้นหลายคลาสสำหรับการประมวลผล ตัวอย่างเช่น StudentNotExistsexception และ StudentExistsexception - - ฯลฯ และรหัสข้อผิดพลาดไม่สามารถระบุได้ซึ่งไม่สะดวกสำหรับ front-end ในการประมวลผลตามรหัสข้อผิดพลาด
หมายเหตุ: กระแสการประมวลผลแบบจำลองสปริงสปริงทั่วไปมีดังนี้
เลเยอร์คอนโทรลเลอร์ทั่วไป-> เลเยอร์บริการ-> เลเยอร์ DAO
1. เลเยอร์คอนโทรลเลอร์ยอมรับคำขอดำเนินการเพจและห่อหุ้มวัตถุ DTO
2. เลเยอร์บริการ, ตรรกะการดำเนินการ, การควบคุมพร้อมกันและธุรกรรม
3.DAO LAYER โต้ตอบกับฐานข้อมูล
ใช้ตารางนักเรียนเพื่ออธิบายการประมวลผล:
1. กำหนดข้อผิดพลาดทั่วไป enum studentExceptionenum
Public Enum StudentExceptionEnum {Student_not_exist (1004, "นักเรียนไม่มีอยู่โปรดยืนยันก่อนที่จะตรวจสอบ"), student_exist (1005, "นักเรียนมีอยู่แล้ว"); สถานะจำนวนเต็มส่วนตัว ความคิดเห็นสตริงส่วนตัว; StudentExceptionEnum (สถานะจำนวนเต็ม, ความคิดเห็นสตริง) {this.status = สถานะ; this.comment = ความคิดเห็น; } จำนวนเต็มสาธารณะ getStatus () {สถานะการส่งคืน; } โมฆะสาธารณะ setStatus (สถานะจำนวนเต็ม) {this.status = สถานะ; } public String getComment () {return comment; } โมฆะสาธารณะ setComment (ความคิดเห็นสตริง) {this.comment = ความคิดเห็น; -2 กำหนดคลาสผลการประมวลผลขั้นพื้นฐาน requestresult
@Datapublic class requestResult {ข้อความสตริงส่วนตัว; สถานะจำนวนเต็มส่วนตัว ข้อมูลวัตถุส่วนตัว Public RequestResult (ข้อความสตริง, สถานะจำนวนเต็ม, ข้อมูลวัตถุ) {this.message = ข้อความ; this.status = สถานะ; this.data = ข้อมูล; } Public RequestResult (ข้อความสตริงสถานะจำนวนเต็ม) {this.message = ข้อความ; this.status = สถานะ; } Public RequestResult (ข้อความสตริงสถานะจำนวนเต็ม) {this.message = ข้อความ; this.status = สถานะ; } Public RequestResult (ข้อความสตริง, studentExceptionEnum requestExceptionenum) {this.message = ข้อความ; this.status = requestExceptionenum.getStatus (); } Public RequestResult () {สถานะ = 200; ข้อความ = "ตกลง"; } Public Static RequestResult OK (ข้อมูลวัตถุ) {requestResult result = new RequestResult (); result.setData (ข้อมูล); ผลการกลับมา; } public requestResult exception (ข้อความสตริง, สถานะจำนวนเต็ม) {ส่งคืนคำขอใหม่ (ข้อความ, สถานะ); } public requestResult Exception (ข้อความสตริง, studentExceptionenum requestExceptionenum) {ส่งคืนคำขอใหม่ (ข้อความ, requestExceptionEnum); -3 กิจการนักเรียน
@Datapublic ชั้นเรียนนักเรียนใช้ serializable {รหัสส่วนตัวส่วนตัว; ชื่อเล่นสตริงส่วนตัว; ชื่อสตริงส่วนตัว; อายุ int ส่วนตัว; เซ็กซ์สตริงส่วนตัว; ที่อยู่สตริงส่วนตัว @Override สตริงสาธารณะ toString () {return toStringBuilder.reflectionToString (นี่); -4 ประมวลผลคำขอเพิ่มนักเรียนชื่อเล่นที่ต้องการ รหัสตัวอย่างบริการเท่านั้นที่แสดงที่นี่
@Override Public RequestResult Addstudent (นักเรียนนักเรียน) {ถ้า (StudentDao.QueryIdByNickName (Student.getNickName ()) == NULL) {StudentDao.addstudent (นักเรียน); System.out.println ("เพิ่มสำเร็จ"); นักเรียน = StudentDao.QueryByNickName (Student.getNickName ()); return requestResult.ok (นักเรียน); } else {return requestResult.exception ("ผู้ใช้" + student.getNickName () + "มีอยู่แล้ว", StudentExceptionenum.student_exist); -5 ในเวลานี้สถานการณ์การประมวลผลพื้นฐานเสร็จสมบูรณ์แล้ว การทดสอบพื้นฐานดำเนินการด้านล่าง
5.1 เพิ่มข้อมูลเพื่อนร่วมชั้นใหม่
5.2 เพิ่มอีกครั้งเพื่อให้การทดสอบผิดปกติ
2. ณ จุดนี้มันจะทำโดยทั่วไป แต่มันจะไม่เป็นมิตรที่จะส่งคืนโดยตรงไปยังส่วนหน้าโดยไม่ต้องจัดการกับข้อยกเว้นรันไทม์พื้นฐาน ดังนั้นคุณต้องกำหนดระดับการจัดการข้อยกเว้น RuntimeException ทั่วโลก
คำอธิบายประกอบที่สำคัญที่ต้องใช้ที่นี่: @ExceptionHandler
มีสองประเพณี 1) เพิ่ม @exceptionhandler ลงในคอนโทรลเลอร์ที่จัดการคำขอ ในเวลานี้วิธีนี้จะจัดการกับข้อยกเว้นที่ถูกโยนโดยคอนโทรลเลอร์เท่านั้น
2) ใช้ในระดับการจัดการข้อยกเว้นทั่วโลก ระดับการจัดการข้อยกเว้นทั่วโลกจะต้องทำเครื่องหมายด้วย @RestControllerAdvice หรือ @ControllerAdvice
เราจำเป็นต้องจัดการกับ RuntimeException ทั่วโลกดังนั้นเราจึงใช้วิธีที่สอง แน่นอนว่าสิ่งนี้ได้รับการจัดการสำหรับลูกค้าที่เป็นมิตร เรายังต้องจัดการกับข้อผิดพลาดนี้ เราควรทำอย่างไร? จำเป็นต้องบันทึกข้อมูลที่ไม่ถูกต้องสำหรับการวิเคราะห์และการประมวลผลในอนาคต การบันทึกดำเนินการที่นี่โดยใช้เครื่องบันทึก รหัสมีดังนี้
@RestControllerAdvicePublic คลาส baseexceptionhandler {logger logger แบบคงที่ส่วนตัว = loggerFactory.getLogger (baseExceptionHandler.class); @ExceptionHandler (value = runtimeException.class) Public RequestResult ExceptionHandler (คำขอ httpservletRequest, Exception e) {logerror (คำขอ, e); return requestResult.exception ("มีการจัดการข้อยกเว้นภายในวิศวกรกำลังทำงานเกี่ยวกับการซ่อมแซมฉุกเฉินโปรดกลับมาในภายหลัง ... ", 500); } public static void logerror (คำขอ httpservletrequest, ข้อยกเว้น e) {logger.error ("ที่อยู่คำขอ:" + request.getRequesturl ()); logger.error ("วิธีการร้องขอ:" + request.getMethod ()); logger.error ("ขอ IP:" + getRemoteip (คำขอ)); logger.error ("รายละเอียดข้อผิดพลาด:"); stackTraceElement [] ข้อผิดพลาด = e.getStackTrace (); สำหรับ (stacktraceElement stacktracelement: ข้อผิดพลาด) {logger.error (stacktraceElement.toString ()); }} สตริงคงที่สาธารณะ getRemoteip (คำขอ httpservletRequest) {string ip = request.getheader ("x-forwarded-for"); if (ip == null || ip.length () == 0 || "ไม่ทราบ" .equalsignorecase (ip)) {ip = request.getheader ("proxy-client-ip"); } if (ip == null || ip.length () == 0 || "ไม่ทราบ" .equalsignorecase (ip)) {ip = request.getheader ("wl-proxy-client-ip"); } if (ip == null || ip.length () == 0 || "ไม่ทราบ" .equalsignorecase (ip)) {ip = request.getheader ("http_client_ip"); } if (ip == null || ip.length () == 0 || "unknown" .equalsignorecase (ip)) {ip = request.getheader ("http_x_forwarded_for"); } if (ip == null || ip.length () == 0 || "ไม่ทราบ" .equalsignorecase (ip)) {ip = request.getRemoteaddr (); }} อื่นถ้า (ip.length ()> 15) {string [] ips = ip.split (","); สำหรับ (int index = 0; index <ips.length; index ++) {string strip = (string) ips [index]; if (! ("ไม่ทราบ" .equalsignorecase (strip))) {ip = strip; หยุดพัก; }}} ส่งคืน IP; -ทดสอบเพื่อดูว่ามีผลหรือไม่:
แก้ไขและเพิ่มรหัสข้อมูลนักเรียนดังนี้:
Public RequestResult Addstudent (นักเรียนนักเรียน) {int a = 1/0; if (StudentDao.QueryIdByNickName (student.getNickName ()) == null) {studentdao.addstudent (นักเรียน); System.out.println ("เพิ่มสำเร็จ"); นักเรียน = StudentDao.QueryByNickName (Student.getNickName ()); return requestResult.ok (นักเรียน); } else {return requestResult.exception ("ผู้ใช้" " + student.getNickName () +" 'อยู่แล้ว ", studentExceptionenum.student_exist); -ทำการทดสอบ
ข้อความแสดงข้อผิดพลาดการพิมพ์บนพื้นหลัง
2018-03-26 17: 01: 19.125 ข้อผิดพลาด 9136 --- [NIO-8080-EXEC-2] ChdController.BaseExceptionHandler: ที่อยู่: http: // localhost: 8080/demo1/student2018-03-26 17: 01: 19.125 CHDController.BaseExceptionHandler: วิธีการร้องขอ: Post2018-03-26 17: 01: 19.125 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] CHDController.BaseExceptionHandler: ขอ IP: 0: 0: 0: 0: 0: 0: 0: 0: 0: 0: 0: 0: 0: 0: 0: 0: 0: 9136 --- [NIO-8080-EXEC-2] ChdController.BaseExceptionHandler: รายละเอียดข้อผิดพลาด: 2018-03-26 17: 01: 19.125 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] CHDController.BaseexceptionHand com.huitong.demo.service.studentservice.addstudent (Studentservice.java:71) 2018-03-26 17: 01: 19.125 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] CHDController.BaseexceptionHand com.huitong.demo.controller.studentcontroller.addstudent (StudentController.java:38) 2018-03-26 17: 01: 19.125 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand วิธีการ) 2018-03-26 17: 01: 19.125 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.BaseexceptionHandler: Sun.reflect.nativeMethodaccessorimpl.invoke [NIO-8080-EXEC-2] CHDCONTROLLER.BASEEXceptionHandler: Sun.reflect.DelegatingMethodaccessorimpl.invoke (DelegatingMethodaccessorimpl.java:43) 2018-03-26 17: 01: 19.125 ข้อผิดพลาด chdcontroller.baseexceptionhandler: java.lang.reflect.method.invoke (method.java:498) 2018-03-26 17: 01: 19.125 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand org.springframework.web.method.support.invocablehandlermethod.doinvoke (invocablehandlermethod.java:209) 2018-03-26 17: 01: 19.125 ข้อผิดพลาด 9136 --- [NIO-8080-EXEC-2] Chdcontroller.125 org.springframework.web.method.support.invocablehandlermethod.invokeforrequest (invocablehandlermethod.java:136) 2018-03-26 17: 01: 19.125 ข้อผิดพลาด 9136 --- org.springframework.web.servlet.mvc.method.annotation.servletinvocablehandlermethod.invokeandhandle (servletinvocablehandlermethod.java:102) 2018-03-26 17: 01: 19.125 ข้อผิดพลาด 9136–- chdcontroller.baseexceptionhandler: org.springframework.web.servlet.mvc.method.annotation.requestmappinghandleradapter.invokehandlermethod (requestmappinghandleradapter.java:870) chdcontroller.baseexceptionhandler: org.springframework.web.servlet.mvc.method.annotation.requestmappinghandleradapter.handleinternal (requestmappinghandleradapter.java:776) 2018-03-26 17: 01: 19.125 chdcontroller.baseexceptionhandler: org.springframework.web.servlet.mvc.method.abstracthandlermethodadapter.handle (Abstracthandlermethodadapter.java:87) 2018-03-26 17: 01: 19.129 ข้อผิดพลาด 9129 ChdController.BaseExceptionHandler: org.springframework.web.servlet.dispatcherservlet.dodispatch (dispatcherservlet.java:991) 2018-03-26 17: 01: 19.129 ข้อผิดพลาด 9136 --- org.springframework.web.servlet.dispatcherservlet.doservice (dispatcherservlet.java:925) 2018-03-26 17: 01: 19.129 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.springframework.web.servlet.frameworkservlet.processrequest (frameworkservlet.java:978) 2018-03-26 17: 01: 19.129 ข้อผิดพลาด 9136 --- [NIO-8080-EXEC-2 org.springframework.web.servlet.frameworkservlet.dopost (frameworkservlet.java:881) 2018-03-26 17: 01: 19.129 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.basee javax.servlet.http.httpservlet.service (httpservlet.java:661) 2018-03-26 17: 01: 19.129 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] CHDController.BaseexceptionHand org.springframework.web.servlet.frameworkservlet.service (frameworkservlet.java:855) 2018-03-26 17: 01: 19.130 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand javax.servlet.http.httpservlet.service (httpservlet.java:742) 2018-03-26 17: 01: 19.130 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] CHDController.BaseexceptionHand org.apache.catalina.core.applicationfilterchain.internaldofilter (applicationfilterchain.java:231) 2018-03-26 17: 01: 19.130 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] ChdController.baseexceptionhand :- org.apache.catalina.core.applicationfilterchain.dofilter (applicationfilterchain.java:166) 2018-03-26 17: 01: 19.130 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.apache.tomcat.websocket.server.wsfilter.dofilter (wsfilter.java:52) 2018-03-26 17: 01: 19.130 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.apache.catalina.core.applicationfilterchain.internaldofilter (applicationfilterchain.java:193) 2018-03-26 17: 01: 19.130 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] ChdController.baseexceptionhand :- org.apache.catalina.core.applicationfilterchain.dofilter (applicationfilterchain.java:166) 2018-03-26 17: 01: 19.130 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- com.alibaba.druid.support.http.webstatfilter.dofilter (webstatfilter.java:123) 2018-03-26 17: 01: 19.130 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexe org.apache.catalina.core.applicationfilterchain.internaldofilter (applicationfilterchain.java:193) 2018-03-26 17: 01: 19.130 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] ChdController.baseexceptionhand :- org.apache.catalina.core.applicationfilterchain.dofilter (applicationfilterchain.java:166) 2018-03-26 17: 01: 19.130 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.springframework.web.filter.requestcontextfilter.dofilterinternal (requestcontextfilter.java:99) 2018-03-26 17: 01: 19.130 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller org.springframework.web.filter.onceperrequestfilter.dofilter (ครั้งเดียว org.apache.catalina.core.applicationfilterchain.internaldofilter (applicationfilterchain.java:193) 2018-03-26 17: 01: 19.130 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] ChdController.baseexceptionhand :- org.apache.catalina.core.applicationfilterchain.dofilter (applicationfilterchain.java:166) 2018-03-26 17: 01: 19.130 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.springframework.web.filter.httpputformcontentfilter.dofilterinternal (httpputformcontentfilter.java:109) 2018-03-26 17: 01: 19.130 ข้อผิดพลาด 9136 --- org.springframework.web.filter.onceperrequestfilter.dofilter (ครั้งเดียว org.apache.catalina.core.applicationfilterchain.internaldofilter (applicationfilterchain.java:193) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.apache.catalina.core.applicationfilterchain.dofilter (applicationfilterchain.java:166) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.springframework.web.filter.hiddenhttpmethodfilter.dofilterinternal (hiddenhttpmethodfilter.java:81) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- org.springframework.web.filter.onceperrequestfilter.dofilter (ครั้งเดียว org.apache.catalina.core.applicationfilterchain.internaldofilter (applicationfilterchain.java:193) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.apache.catalina.core.applicationfilterchain.dofilter (applicationfilterchain.java:166) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.springframework.web.filter.characterencodingfilter.dofilterinternal (chailureencodingfilter.java:200) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-EXEC-2 org.springframework.web.filter.onceperrequestfilter.dofilter (ครั้งเดียว org.apache.catalina.core.applicationfilterchain.internaldofilter (applicationfilterchain.java:193) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.apache.catalina.core.applicationfilterchain.dofilter (applicationfilterchain.java:166) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.apache.catalina.core.standardwrappervalve.invoke (Standardwrappervalve.java:199) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.apache.catalina.core.standardcontextvalve.invoke (StandardContextValve.java:96) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] ChdController.Baseexceptionhand :- org.apache.catalina.authenticator.authenticatorbase.invoke (Authenticatorbase.java:496) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.apache.catalina.core.standardhostvalve.invoke (Standardhostvalve.java:140) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.apache.catalina.valves.errorreportvalve.invoke (errorreportvalve.java:81) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.apache.catalina.core.standardenginevalve.invoke (Standardenginevalve.java:87) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.apache.catalina.connector.coyoteadapter.service (Coyoteadapter.java:342) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.apache.coyote.http11.http11processor.service (http11processor.java:803) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexe org.apache.coyote.abstractprocessorlight.process (AbstractProcessorlight.java:66) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] ChdController.Baseexceptionhand org.apache.coyote.abstractprotocol $ connectionhandler.process (Abstractprotocol.java:790) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.apache.tomcat.util.net.nioendpoint $ socketprocessor.dorun (nioendpoint.java:1459) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexe org.apache.tomcat.util.net.socketprocessorbase.run (SocketProcessorbase.java:49) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-EXEC-2] Chdcontroller.baseex java.util.concurrent.threadpoolexecutor.runworker (Threadpoolexecutor.java:1142) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- java.util.concurrent.threadpoolexecutor $ worker.run (threadpoolexecutor.java:617) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] Chdcontroller.baseexceptionhand :- org.apache.tomcat.util.threads.taskthread $ wrappingRunnable.run (tatchThread.java:61) 2018-03-26 17: 01: 19.131 ข้อผิดพลาด 9136 --- [NIO-8080-Exec-2] ChdController.baseexceptionhand :- java.lang.thread.run (thread.java:745) 2018-03-26 17: 01: 19.133 WARN 9136 --- [NIO-8080-Exec-2] .MmaexceptionHandlerexceptionResolver: ข้อยกเว้น
สรุป
ข้างต้นเป็นบทสรุปการจัดการข้อผิดพลาดของ Springboot ที่แนะนำโดยตัวแก้ไข ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับทุกคนในเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!