الخلاصة: في الآونة الأخيرة ، هناك شرط لتزويد العملاء ببعض واجهات API المريحة. تستخدم QA Postman للاختبار ، ولكن واجهة اختبار Postman متشابهة ولكن ليس مثل مكالمات Java. لذلك أريد أن أكتب برنامجًا لاختبار واجهة API Restful بنفسي. نظرًا لأنه يستخدم HTTPS ، أحتاج أيضًا إلى النظر في معالجة HTTPS. منذ أن استخدمت Java للاتصال بالواجهة المريحة لأول مرة ، ما زلت بحاجة إلى دراستها ، لذلك استشرت بشكل طبيعي بعض المعلومات.
التحليل: تختلف هذه المشكلة عن المكالمات بين الوحدات النمطية. على سبيل المثال ، لديّ وحدتان ، الواجهة الأمامية والخلفية ، يوفر الواجهة الأمامية عرضًا أماميًا ، ويوفر الطرف الخلفي دعم البيانات. لقد استخدمت Hession لتسجيل الخدمات المقدمة في النهاية الخلفية كخدمات عن بُعد. على الواجهة الأمامية ، يمكن ضبط هذه الخدمة عن بُعد مباشرة على واجهة النهاية الخلفية من خلال هذا النوع من الخدمة عن بُعد. ولكن هذه ليست مشكلة بالنسبة للشركة لاستخدامها عندما يكون مشروعها مقترنًا للغاية. ومع ذلك ، إذا قمت بتسجيل هذه الخدمة عن بُعد مع العملاء ، فإنها ليست جيدة والاقتران مرتفع للغاية. لذلك أنا أفكر في استخدام الطريقة التالية.
1. httpclient
قد يكون الجميع على دراية بـ httpclient ولكنه غير مألوف معها. إنه على دراية به لأنه يمكنه الاتصال عن بُعد ، على سبيل المثال ، طلب عنوان URL ، ثم الحصول على حالة الإرجاع وإرجاع المعلومات في الاستجابة. ومع ذلك ، أنا أتحدث اليوم أكثر تعقيدًا ، لأن موضوع اليوم هو HTTPS ، والذي يتضمن مشكلة الشهادات أو مصادقة المستخدم.
بعد التأكيد على أنه باستخدام HTTPClient ، بحثت عن المعلومات ذات الصلة ووجدت أن الإصدار الجديد من HTTPClient يختلف عن الإصدار القديم ، وهو متوافق مع الإصدار القديم ، لكن لم يعد يوصى باستخدام الإصدار القديم. تم وضع علامة على العديد من الأساليب أو الفئات القديمة. اليوم ، سوف نستخدم الإصدار القديم 4.2 وأحدث الإصدار 4.5.3 لكتابة الرمز على التوالي.
الإصدار القديم 4.2
الحاجة للحصول على شهادة
يتم تحديد استخدام مصادقة الشهادة أثناء مرحلة إعداد الشهادة
حزمة com.darren.test.https.v42 ؛ استيراد java.io.file ؛ استيراد java.io.fileInputStream ؛ استيراد java.security.keystore ؛ استيراد org.apache.http.conn.ssl.sslsocketfactory ؛ الفئة العامة httpscertifiedclient يمتد httpsclient {public httpscertifiedclient () {} override public void prepareCertificate () rems {// الحصول على keystore keystore keystore keystore.getInstance (keystore.getDefaulttype ()) ؛ FileInputStream input = new FileInputStream (ملف جديد ("C: /users/zhda6001/downloads/software/xxx.keystore")) ؛ // fileInputStream input = new FileInputStream (ملف جديد ("c: /users/zhda6001/downloads/xxx.keystore")) ؛ // كلمة مرور المكتبة الرئيسية ائتمان. // قم بتسجيل مكتبة المفتاح this.socketfactory = sslsocketfactory جديد (ائتمان) ؛ // لا تحقق من اسم المجال socketfactory.SethostNameverifier (sslsocketfactory.allow_all_hostname_verifier) ؛ }}تخطي الشهادة
خيار تخطي المصادقة أثناء مرحلة إعداد الشهادة هو
حزمة com.darren.test.https.v42 ؛ استيراد java.security.cert.certificateException ؛ استيراد java.security.cert.x509certificate ؛ استيراد javax.net.ssl.sslcontext ؛ استيراد javax.net.ssl.trustmanager ؛ استيراد javax.net.ssl.x509trustmanager ؛ استيراد org.apache.http.conn.ssl.sslsocketfactory ؛ الفئة العامة HTTPSTRUSTCLIENT يمتد httpsclient {public httpstrustclient () {} Override public void preparedEcertificate () rems {// skip certificate compreation sslcontext ctx = sslContext.getInstance ("tls") ؛ X509TRUSTMANAGER TM = جديد X509TRUSTMANAGER () x509Certificate [] getAcceptedissuers () {return null ؛ }} ؛ // ضبط على الشهادة الموثوقة ctx.init (null ، new trustmanager [] {tm} ، null) ؛ // ضع مصنع SSL Socket ، وقم بتعيين عدم التحقق من اسم المضيف this.socketfactory = sslsocketfactory جديد (ctx ، sslsocketfactory.allow_all_hostname_verifier) ؛ }}لخص
الآن وجد أن كلا الفئتين يرثون نفس الفئة httpsclient ، ويرث Httpsclient فئة defaulthttpclient. يمكن العثور على أن نمط طريقة القالب يستخدم هنا.
حزمة com.darren.test.https.v42 ؛ استيراد org.apache.http.conn.clientConnectionManager ؛ استيراد org.apache.http.conn.scheme.scheme ؛ استيراد org.apache.http.conn.ssl.sslsocketfactory ؛ استيراد org.apache.http.impl.client.defaulthttpclient ؛ الفئة المجردة العامة httpsclient يمتد defaulthttpclient {محمية sslsocketfactory saceterfactory ؛ / ** * تهيئة httpsclient * * return إرجاع المثيل الحالي * throws استثناء */ public httpsclient init () يلقي الاستثناء {this.prepareCertificate () ؛ this.regist () ؛ إرجاع هذا ؛ } / ** * إعداد التحقق من الشهادة * * Throws استثناء * / Public Abstract void prepareCertificate () رمي الاستثناء ؛ / *** تسجيل بروتوكول ومنفذ ، يمكن إعادة كتابة هذه الطريقة أيضًا بواسطة الفئات الفرعية*/ void void المحمية () {clientConnectionManager ccm = this.getConnectionManager () ؛ Schemeregistry sr = ccm.getSchemeregistry () ؛ sr.register (مخطط جديد ("https" ، 443 ، socketFactory)) ؛ }} فيما يلي فئة الأدوات
حزمة com.darren.test.https.v42 ؛ استيراد java.util.arraylist ؛ استيراد java.util.list ؛ استيراد java.util.map ؛ استيراد java.util.set ؛ استيراد org.apache.http.httpentity ؛ استيراد org.apache.http.httpresponse ؛ استيراد org.apache.http.namevaluepair ؛ استيراد org.apache.http.client.entity.urlencodedformentity ؛ استيراد org.apache.http.client.methods.httpget ؛ استيراد org.apache.http.client.methods.httppost ؛ استيراد org.apache.http.client.methods.httprequestbase ؛ استيراد org.apache.http.message.basicnamevaluepair ؛ استيراد org.apache.http.util.entityUtils ؛ الفئة العامة httpsclientutil {private static final string default_charset = "utf-8" ؛ السلسلة الثابتة العامة dopost (httpsclient httpsclient ، url سلسلة ، خريطة <سلسلة ، سلسلة> paramheader ، خريطة <سلسلة ، سلسلة> parambody) يلقي الاستثناء {return dopost (httpsclient ، url ، paramhoder ، parambody ، default_charset) ؛ } السلسلة الثابتة العامة dopost (httpsclient httpsclient ، url سلسلة ، خريطة <string ، string> paramheader ، خريطة <string ، string> parambody ، سلسلة charset) يلقي استثناء {String result = null ؛ httppost httppost = new httppost (url) ؛ Setheader (httppost ، paramheader) ؛ setBody (httppost ، parambody ، charset) ؛ httpresponse استجابة = httpsclient.execute (httppost) ؛ if (resentity! = null) {httpentity resentity = response.getentity () ؛ if (resentity! = null) {result = entityUtils.ToString (resentity ، charset) ؛ }} نتيجة الإرجاع ؛ } سلسلة ثابتة للسلسلة الثابتة (httpsclient httpsclient ، url سلسلة ، خريطة <string ، string> paramheader ، خريطة <string ، string> parambody) يلقي الاستثناء {return doge (httpsclient ، url ، paramhoder ، parambody ، default_charset) ؛ } السلسلة الثابتة العامة doget (httpsclient httpsclient ، url url string ، خريطة <string ، string> paramheader ، خريطة <string ، string> parambody ، string charset) يلقي استثناء {string result = null ؛ httpget httpget = new httpget (url) ؛ Setheader (httpget ، paramheader) ؛ httpresponse استجابة = httpsclient.execute (httpget) ؛ if (response! = null) {httpentity resentity = response.getentity () ؛ if (resentity! = null) {result = entityUtils.ToString (resentity ، charset) ؛ }} نتيجة الإرجاع ؛ } private static void setheader (httprequestbase request ، map <string ، string> paramheader) {// set header if (paramheader! = null) {set <String> keyset = paramheader.keyset () ؛ لـ (مفتاح السلسلة: KeySet) {request.addheader (المفتاح ، paramheader.get (مفتاح)) ؛ }}} private static void setbody (httppost httppost ، map <string ، string> parambody ، string charset) يرمي استثناء {// قم بتعيين المعلمة if (parambody! = null) {list <MameValUepair> list = new ArrayList <Aamevaluepair> () ؛ SET <STRING> KEYSET = PARAMBODY.KEYSET () ؛ لـ (مفتاح السلسلة: keyset) {list.add (new BasicNameValUepair (Key ، parambody.get (key))) ؛ } if (list.size ()> 0) {urlencodedformentity ictity = new urlencodedformentity (list ، charset) ؛ httppost.setentity (الكيان) ؛ }}}} ثم هناك فئة الاختبار:
حزمة com.darren.test.https.v42 ؛ استيراد java.util.hashmap ؛ استيراد java.util.map ؛ الفئة العامة httpsclientest {public static void main (string [] args) يلقي الاستثناء {httpsclient httpsclient = null ؛ httpsclient = new httpstrustclient (). init () ؛ // httpsclient = جديد httpscertifiedclient (). init () ؛ String url = "https://1.2.6.2:8011/xxx/api/gettoken" ؛ // String url = "https://1.2.6.2:8011/xxx/api/gethealth" ؛ خريطة <string ، string> paramheader = new hashmap <> () ؛ //paramheader.put("content-type "،" application/json ") ؛ paramheader.put ("قبول" ، "تطبيق/xml") ؛ الخريطة <string ، string> parambody = new hashmap <> () ؛ parambody.put ("client_id" ، "[email protected]") ؛ parambody.put ("client_secret" ، "p@ssword_1") ؛ سلسلة السلسلة = httpsclientutil.dopost (httpsclient ، url ، paramheader ، parambody) ؛ // string result = httpsclientutil.doget (httpsclient ، url ، null ، null) ؛ System.out.println (نتيجة) ؛ }} معلومات العودة:
<؟
<token> jkf8rl0sw+skkflj8rbki5hp1beqk8prcutzppbinqmykrmxy1kwcjmcft191zpp8vv1aghw8oynwjeys 0axplugax89ejcownbikcc1uvfyesxhlktcjqyufivjevhreqxjphnclqywp+xse5od9x8vkfk7inntmrzqk7ybtz /e3u7gswm/5cvahfl6o9req9cwpxavznohyvnxsoszdo+bxatxa1xpedly/8h/uap4n4dlzdjj3b8t1xh+crriom OPXF7C5WKHTOKEOEXW+XOPQKKSX5CKWWJPUGIIFWF/PAQWG+JUOSVT7QGDPV8PMWJ9DWEWWJTDXGUDG == </TOKEN>
الإصدار الجديد 4.5.3
الحاجة للحصول على شهادة
حزمة com.darren.test.https.v45 ؛ استيراد java.io.file ؛ استيراد java.io.fileInputStream ؛ استيراد java.security.keystore ؛ استيراد javax.net.ssl.sslcontext ؛ استيراد org.apache.http.conn.ssl.sslconnectionsocketFactory ؛ استيراد org.apache.http.conn.ssl.sslconnectionsocketFactory ؛ استيراد org.apache.http.conn.ssl.TrustselfSignedStrategy ؛ استيراد org.apache.http.ssl.sslcontexts ؛ الفئة العامة httpscertifiedclient يمتد httpsclient {public httpscertifiedclient () {} override public void prepareCertificate () rems {// الحصول على keystore keystore keystore keystore.getInstance (keystore.getDefaulttype ()) ؛ FileInputStream Instream = جديد fileInputStream (ملف جديد ("C: /users/zhda6001/downloads/software/xxx.keystore")) ؛ ] جرب {// كلمة مرور مكتبة المفاتيح ائتمان. } أخيرًا {entersream.close () ؛ } sslContext sslcontext = sslcontexts.custom (). loadtrustmaterial (truststore ، rustselfsignedstrategy.instance) .build () ؛ this.connectionsocketFactory = جديد sslConnectionSocketFactory (sslContext) ؛ }}تخطي الشهادة
حزمة com.darren.test.https.v45 ؛ استيراد java.security.cert.certificateException ؛ استيراد java.security.cert.x509certificate ؛ استيراد javax.net.ssl.sslcontext ؛ استيراد javax.net.ssl.trustmanager ؛ استيراد javax.net.ssl.x509trustmanager ؛ استيراد org.apache.http.conn.ssl.sslconnectionsocketFactory ؛ الفئة العامة HTTPSTRUSTCLIENT يمتد httpsclient {public httpstrustclient () {} Override public void preparedEcertificate () rems {// skip certificate compreation sslcontext ctx = sslContext.getInstance ("tls") ؛ X509TRUSTMANAGER TM = جديد X509TRUSTMANAGER () x509Certificate [] getAcceptedissuers () {return null ؛ }} ؛ // ضبط على شهادة موثوقة ctx.init (null ، new trustmanager [] {tm} ، null) ؛ this.connectionsocketFactory = جديد sslConnectionSocketFactory (CTX) ؛ }}لخص
حزمة com.darren.test.https.v45 ؛ استيراد org.apache.http.config.registry ؛ استيراد org.apache.http.config.registrybuilder ؛ استيراد org.apache.http.conn.socket.connectionsocketFactory ؛ استيراد org.apache.http.conn.socket.plainconnectionsocketFactory ؛ استيراد org.apache.http.impl.client.closablehttpclient ؛ استيراد org.apache.http.impl.client.httpclientbuilder ؛ استيراد org.apache.http.impl.client.httpclients ؛ استيراد org.apache.http.impl.conn.poolinghttpclientConnectionMonager ؛ الفئة المجردة العامة httpsclient يمتد httpclientbuilder {private closablehttpclient client ؛ ConnectionSocketFactory ConnectionSocketFactory ؛ / ** * تهيئة httpsclient * * return إرجاع المثيل الحالي * athrows استثناء */ public clostablehttpclient init () يلقي الاستثناء {this.prepareCertificate () ؛ this.regist () ؛ إرجاع هذا. } / ** * إعداد التحقق من الشهادة * * Throws استثناء * / Public Abstract void prepareCertificate () رمي الاستثناء ؛ / *** تسجيل البروتوكول والمنفذ ، يمكن أيضًا إعادة كتابة هذه الطريقة بواسطة الفئات الفرعية*/ REGIST VOID المحمية () {// قم بتعيين الكائن المقابل للبروتوكول HTTP و HTTPS الذي يتولى سجل Link Factory <ConnectionSocketFactory> socketfactoryregistry = RegistryBuilder. PlainConnectionsOctionFactory.instance) .register ("https" ، this.connectionsCetCoStory) .build () ؛ poolinghttpclientConnectionManager connmanager = new poolingHttpClientConnectionManager (SocketFactoryregistry) ؛ httpclients.custom (). setConnectionManager (connmanager) ؛ // إنشاء كائن httpclient مخصص this.client = httpclients.custom (). setConnectionManager (connmanager) .build () ؛ // closeablehttpclient client = httpclients.createdefault () ؛ }} أدوات:
حزمة com.darren.test.https.v45 ؛ استيراد java.util.arraylist ؛ استيراد java.util.list ؛ استيراد java.util.map ؛ استيراد java.util.set ؛ استيراد org.apache.http.httpentity ؛ استيراد org.apache.http.httpresponse ؛ استيراد org.apache.http.namevaluepair ؛ استيراد org.apache.http.client.httpclient ؛ استيراد org.apache.http.client.entity.urlencodedformentity ؛ استيراد org.apache.http.client.methods.httpget ؛ استيراد org.apache.http.client.methods.httppost ؛ استيراد org.apache.http.client.methods.httprequestbase ؛ استيراد org.apache.http.message.basicnamevaluepair ؛ استيراد org.apache.http.util.entityUtils ؛ الفئة العامة httpsclientutil {private static final string default_charset = "utf-8" ؛ السلسلة الثابتة العامة dopost (httpclient httpclient ، url سلسلة ، خريطة <سلسلة ، سلسلة> paramheader ، خريطة <سلسلة ، سلسلة> parambody) يلقي الاستثناء {return dopost (httpclient ، url ، parameder ، parambody ، default_charset) ؛ } السلسلة الثابتة العامة dopost (httpclient httpclient ، url سلسلة ، خريطة <string ، string> paramheader ، خريطة <string ، string> parambody ، سلسلة charset) رمي استثناء {String result = null ؛ httppost httppost = new httppost (url) ؛ Setheader (httppost ، paramheader) ؛ setBody (httppost ، parambody ، charset) ؛ httpresponse استجابة = httpclient.execute (httppost) ؛ if (resentity! = null) {httpentity resentity = response.getentity () ؛ if (resentity! = null) {result = entityUtils.ToString (resentity ، charset) ؛ }} نتيجة الإرجاع ؛ } سلسلة ثابتة للسلسلة الثابتة (httpclient httpclient ، url سلسلة ، خريطة <string ، string> paramheader ، خريطة <string ، string> parambody) يلقي الاستثناء {return doge (httpclient ، url ، paramhoder ، parambody ، default_charset) ؛ } السلسلة الثابتة العامة dogge (httpclient httpclient ، url url سلسلة ، خريطة <سلسلة ، سلسلة> paramheader ، خريطة <string ، string> parambody ، سلسلة charset) رمي الاستثناء {string result = null ؛ httpget httpget = new httpget (url) ؛ Setheader (httpget ، paramheader) ؛ httpresponse استجابة = httpclient.execute (httpget) ؛ if (response! = null) {httpentity resentity = response.getentity () ؛ if (resentity! = null) {result = entityUtils.ToString (resentity ، charset) ؛ }} نتيجة الإرجاع ؛ } private static void setheader (httprequestbase request ، map <string ، string> paramheader) {// set header if (paramheader! = null) {set <String> keyset = paramheader.keyset () ؛ لـ (مفتاح السلسلة: KeySet) {request.addheader (المفتاح ، paramheader.get (مفتاح)) ؛ }}} private static void setbody (httppost httppost ، map <string ، string> parambody ، string charset) يرمي استثناء {// قم بتعيين المعلمة if (parambody! = null) {list <MameValUepair> list = new ArrayList <Aamevaluepair> () ؛ SET <STRING> KEYSET = PARAMBODY.KEYSET () ؛ لـ (مفتاح السلسلة: keyset) {list.add (new BasicNameValUepair (Key ، parambody.get (key))) ؛ } if (list.size ()> 0) {urlencodedformentity ictity = new urlencodedformentity (list ، charset) ؛ httppost.setentity (الكيان) ؛ }}}}}} فئة الاختبار:
حزمة com.darren.test.https.v45 ؛ استيراد java.util.hashmap ؛ استيراد java.util.map ؛ استيراد org.apache.http.client.httpclient ؛ الفئة العامة httpsclientest {public static void main (string [] args) يلقي الاستثناء {httpclient httpclient = null ؛ // httpclient = new httpstrustclient (). init () ؛ httpclient = جديد httpscertifiedclient (). init () ؛ String url = "https://1.2.6.2:8011/xxx/api/gettoken" ؛ // String url = "https://1.2.6.2:8011/xxx/api/gethealth" ؛ خريطة <string ، string> paramheader = new hashmap <> () ؛ paramheader.put ("قبول" ، "تطبيق/xml") ؛ الخريطة <string ، string> parambody = new hashmap <> () ؛ parambody.put ("client_id" ، "[email protected]") ؛ parambody.put ("client_secret" ، "p@ssword_1") ؛ النتيجة السلسلة = httpsclientutil.dopost (httpclient ، url ، paramheader ، parambody) ؛ // string result = httpsclientutil.doget (httpsclient ، url ، null ، null) ؛ System.out.println (نتيجة) ؛ }} نتيجة:
<؟
<token> rxitf9 // 7nxwxjs2cjijyhltvzunvmzxeqtgn0u07sc9yibpqte3hcjulskoxpeugevyi9jv7/wi klrzxykc3ospatsm0kcbckphu0tb2cn/nfzv9fmlueowfbdyz+n0seii9k+0gp7920dfencn17wujvmc0u2jwvm5fa JQKMILWODXZ6A0DQ+D7DQDJWVCWXBVJ2ILHYIB3PR805VPPMI9ATXRVAKO0ODA006WEJFOFCGYG5P7WPJ5RRBL85V fy9wcvkd1r7j6nvjhxgh2gnimhkjeJormjdxw2gkiusiwseli/xpswao7/ctwnwtnctgk8px2zub0zfa == </token>
2. httpurlconnection
3. الربيع resttemplate
سيتم استكمال طرق أخرى لاحقًا
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.