Résumé: Récemment, il est nécessaire de fournir aux clients des interfaces API reposantes. QA utilise Postman pour les tests, mais l'interface de test de Postman est similaire mais pas la même chose que les appels Java. Je veux donc écrire un programme pour tester par moi-même l'interface API RESTful. Puisqu'il utilise HTTPS, je dois également considérer le traitement de HTTPS. Comme j'ai utilisé Java pour appeler l'interface RESTful pour la première fois, j'ai encore besoin de l'étudier, donc j'ai naturellement consulté certaines informations.
Analyse: Ce problème est différent des appels entre les modules. Par exemple, j'ai deux modules Frontend et Backend. Frontend fournit un affichage Frontend et le backend fournit une prise en charge des données. J'ai utilisé Hession pour enregistrer les services fournis par Backend en tant que services à distance. Du côté frontal, ce service à distance peut être directement ajusté à l'interface backend. Mais ce n'est pas un problème pour une entreprise à utiliser lorsque son propre projet est fortement couplé. Cependant, si vous enregistrez un tel service à distance avec les clients, il ne semble pas bon et le couplage est trop élevé. J'envisage donc d'utiliser la méthode suivante.
Introduction de base
Pour l'appel de l'interface Restful, le frontal utilise généralement l'appel Ajax et le back-end peut utiliser plus de méthodes.
Cette fois, trois types sont introduits:
1.HttpurlConnection Implémentation
2. HttpClient Implémentation
3. Restemplate de Spring
1. HttpClient
Tout le monde est peut-être familier avec HttpClient mais ne le connaît pas. Il le connaît car il peut appeler à distance, par exemple, demander une URL, puis obtenir l'état de retour et les informations de retour dans la réponse. Cependant, aujourd'hui, j'en parle un peu plus, car le sujet d'aujourd'hui est HTTPS, ce qui implique le problème des certificats ou de l'authentification des utilisateurs.
Après avoir confirmé que l'utilisation de HTTPClient, j'ai recherché des informations pertinentes et j'ai constaté que la nouvelle version de HttpClient est différente de l'ancienne version et est compatible avec l'ancienne version, mais il n'est plus recommandé que l'ancienne version soit utilisée. De nombreuses méthodes ou classes ont été marquées comme obsolètes. Aujourd'hui, nous utiliserons l'ancienne version 4.2 et la dernière version 4.5.3 pour écrire le code respectivement.
Ancienne version 4.2
Besoin de certification
L'utilisation de l'authentification du certificat est sélectionnée pendant la phase de préparation du certificat
Package com.darren.test.https.v42; import java.io.file; import java.io.fileInputStream; import java.security.keystore; import org.apache.http.conn.ssl.sslsocketfactory; public class httpScertifentientclieny {} @Override public void prepareCertificate () lève une exception {// obtenez la bibliothèque de clés keystore truststore = keystore.getInstance (keystore.getDefaultType ()); fileInputStream input = newInputStream (nouveau fichier ("c: / users/zhda6001/downloads/software/xx.key"); //xx.key ")); FileInputStream Input = new FileInputStream (nouveau fichier ("c: /users/zhda6001/downloads/xxx.keystore")); // Mot de passe de la bibliothèque de clés TrustStore.load (Instream, "Mot de passe" .toCharArray ()); // Enregistrez la bibliothèque de clés this.socketfactory = new SSLSocketFactory (TrustStore); // ne vérifie pas le nom de domaine socketfactory.sethostnameverifier);Sauter la certification
L'option de sauter l'authentification pendant la phase de préparation du certificat est de
package com.darren.test.https.v42; import java.security.cert.certificateException; import java.security.cert.x509certificate; import javax.net.ssl.sslcontext; import javax.net.ssl.trustmanager; org.apache.http.conn.ssl.sslsocketfactory; public class httpstrustClient étend httpsClient {public httpstrustClient () {} @Override public void prepareCertificate () lance l'exception {// skip Verification sslcontext ctx = Sslcontext.getInstance ("tls"); x509TrustManager tm = new x509TrustManager () {@Override public Void CheckClientTruted (x509Certificate [] chaîne, chaîne AuthType) lance CertificateException {} @Override Public Checktype) CertificateException {} @Override public x509Certificate [] getACceptedSisuers () {return null;}}; // défini sur le certificat de confiance ctx.init (null, new TrustManager [] {tm}, null); // met la socket ssl et définie pour vérifier l'hôte Sslsocketfactory (ctx, sslsocketfactory.allow_all_hostname_verifier);}}Résumer
Maintenant, il est constaté que les deux classes héritent de la même classe httpsclient, et httpsClient hérite de la classe DefaulthTTPClient. On peut constater que le modèle de méthode de modèle est utilisé ici.
package com.darren.test.https.v42; import org.apache.http.conn.clientConnectionManager; import org.apache.http.conn.scheme.scheme; import org.apache.http.conn.ssl.sslsocketfactory; org.apache.http.impl.client.defaulthttpclient; public abstract class httpsClient étend DefaulthTTPClient {Protected sslsocketfactory socketfactory; / ** * initialize httpsclient * * @return return the actuel instruction @throws exception * / public httcly {this.prepareCertificate (); this.Regist (); renvoie ce this.getConnectionManager (); SchemeRegistry sr = ccm.getschemeRegistry (); sr.register (nouveau schéma ("https", 443, socketfactory));}}Vous trouverez ci-dessous la classe d'outils
package com.darren.test.https.v42; import java.util.arraylist; import java.util.list; import java.util.map; import java.util.set; import org.apache.http.httpentity; import org.apache.http.httpruse; importation; import org.apache.http.namevaluepair; import org.apache.http.client.entity.urlencodedFormentity; import org.apache.http.client.methods.httpget; import org.apache.http.client.methods.httprequestbase; import org.apache.http.message.basicNameValuepair; import org.apache.http.util.entityutils; public class httpsclientutil {private static string string default_charset = "utf-8"; public static static static static final string default_Charet = "utf-8"; public static static string static string string final default_carnet = "utf-8"; public static static string string string string string default_ChartET = "utf-8"; public static static static static final string string_carred_Charet = "utf-8"; Public String String STRING STATIQU dopost (httpsclient httpsclient, string url, map <string, string> paramheader, map <string, string> parambody) lève exception {return doPost (httpsclient, url, paramheader, parambody, default_charset);} public stating string dopost (httpsclient httpsclient, string url, maph Parambody, String Charset) lève une exception {String result = null; httppost httppost = new httppost (url); sethader (httppost, paramheader); setbody (httppost, parambody, charset); httpResponse = httpsClient.Executy respect); if (réponse! = null) {httt Response.gentity (); if (resentity! = null) {result = entityUtils.tostring (Resentity, charset);}} return result;} public static string doget (httpsclient httpsclient, string url, map <string, string> paramheder, map <string, parambody) throws exception {return doget (httscl Default_Charset);} public static String doGet (httpsClient httpsClient, string url, map <string, string> paramheader, map <string, string> parambody, string charset) lève exception {string result = null; httpget httpget = new httpget (url); httpget, paramheler); httprerse httpsClient.Execute (httpget); if (réponse! = null) {httpentity resentity = réponse.gentity (); if (resentity! = null) {result = entityUtils.tostring (Resentity, charset);}} Retour Result;} Priva {// set en-tête if (paramheader! = Null) {set <string> keyset = paramheader.keyset (); for (string key: keyset) {request.addheader (key, paramheadher.get (key));}}} private static set setbody (httppost httppost, map <string, string> param (parambody! = null) {list <nameValuepair> list = new ArrayList <nameValuepair> (); set <string> keyset = parambody.keyset (); for (string key: keyset) {list.add (new BasicNameValuepair (key, parambody.get (key)));} if (list.size ()> 0) {urlenced));} if (list.size ()> 0) {urlenced));} if (list.size ()> 0) {urlenced))) UrLenCcodedFormentity (List, Charset); httppost.sentity (entité);}}}}Ensuite, il y a la classe de test:
package com.darren.test.https.v42; import java.util.hashmap; import java.util.map; public class httpsClientTest {public static void main (string [] args) lance exception {httpsclient httpsclient = null; httpsclient = new HttpstrustClient (). Init (); // httpsClient = new httpsCertifiedClient (). Init (); String url = "https://1.2.6.2:8011/xxx/api/getToken" Map <string, string> paramheader = new hashmap <> (); // paramheader.put ("contenu-type", "application / json"); paramheader.put ("accepter", "application / xml"); Map <string, string> parambody = new hashmap <> (); parambody.put ("client_id", "[email protected]"); parambody.put ("client_secret", "p @ sword_1"); string result = httpsclientutil. // string (httpsclient, url, paramheler, parambody); HttpsClientUtil.doget (httpsclient, url, null, null); System.out.println (résultat);}}Informations de retour:
<? xml version = "1.0" Encoding = "utf-8"?> <Token> jkf8rl0Sw + skkflj8rBKI5HP1BEQK8PRCUTZPPBINQMYKRMXY1KWCJMCFT191ZPP88VV1AGHW8OYNWJEYS 0axplugax89ejcownbikcc1uvfyesxhlktcjqyufivjevhreqxjphnclqywp + xse5od9x8vkfkk7inntmrzqk7ybtz / e3u7gswm / 5cvahfl6o9req9cwpxavznohyvnxsohszdo + bxatxxa1xpedly / 8h / uap4n4dlzdjj3b8t1xh + crriom OPXF7C5WKHHTOKEOEXW + XOPQKKSX5CKWWJPUGIIFWF / PAQWG + JUOSVT7QGDPV8PMWJ9DWEWJTDXGUDG == </ Token>
Nouvelle version 4.5.3
Besoin de certification
package com.darren.test.https.v45; import java.io.file; import java.io.fileInputStream; import java.security.keystore; import javax.net.ssl.sslcontext; import org.apache.http.conn.ssl.sslconnection bocketfactory; import; org.apache.http.conn.ssl.sslconnectionSocketFactory; import org.apache.http.conn.ssl.trustselfsignedStrategy; Import org.apache.http.ssl.sslcontexts; public class httScertifiedClient extend httpsClient {public httpscredClient () {} @Override public void prepareCertificate () lève une exception {// Obtenez la bibliothèque de clés keystore de keystore = keystore.getInstance (keystore.getDefaultType ()); fileInputStream = FileInputStream InsideRam = new FileInputStream (nouveau fichier ("c: /users/zhda6001/downloads/xxx.keystore")); essayez {// mot de passe de la bibliothèque de clés trustStore.load (insideam, "mot de passe" .toCharArray ());} enfin {instream.close ();} sslcontext sslContext = sslcontex.custom (). LoadTrustMaterial (TrustStore, TrustSignedStrategy.instance) .Build (); this.connectionsocketfactory = new sslconnectionsocketfactory (sslContext);}}Sauter la certification
package com.darren.test.https.v45; import java.security.cert.certificateException; import java.security.cert.x509certificate; import javax.net.ssl.sslcontext; import javax.net.ssl.trustmanager; org.apache.http.conn.ssl.sslconnectionSocketFactory; public class httpstrustClient étend httpsClient {public httpstrustClient () {} @Override public void prepareCertificate () lance une exception {// skip vérification sslcontext ctx = Sslcontext.getInstance ("tls"); x509TrustManager tm = new x509TrustManager () {@Override public Void CheckClientTruted (x509Certificate [] chaîne, chaîne AuthType) lance CertificateException {} @Override Public Checktype) CertificateException {} @Override public void checkServerTruted (x509certificate [] chaîne, string authType) lève CertificateException {} @Override public x509certificate [] getACceptedSisuers () {return null;}}; // mis sur un certificat fiduci null); this.connectionsocketfactory = new sslconnectionsocketfactory (ctx);}}Résumer
package com.darren.test.https.v45; import org.apache.http.config.registry; import org.apache.http.config.registrybuilder; import org.apache.http.conne.socket.connectionSocketFactory; import org.apache.http.connex org.apache.http.impl.client.closeablehttpclient; import org.apache.http.impl.client.httpclientbuilder; import org.apache.http.impl.client.httpclients; import org.apache.httpp.impl.connex. classe httpsClient étend httpclientBuilder {Client de fermeture privée; this.client;} / ** * Préparer la vérification du certificat * * @throws exception * / public abstract void prepareCertificate () lève une exception; / ** * Registre protocole et port, cette méthode peut également être réécrit par sous-classe * / VOID REGIST () {// Définit l'objet correspondant à ProtoCol HTTPT et HTTPS That Handles Socket Link Reinked Factory Cherchy SocketFactoryRegistry = RegistryBuilder. <ConnectionsocketFactory> create () .Register ("http", PlainConnectionSocketFactory.instance) .Register ("https", this.connectionSocketFactory) .build (); PolingHttpClientConnectionManAgerger Connmanager = new PooringHttpClientConnectionManager (socketfactoryRegistry); httpclients.custom (). SetConnectionManager (ConnManager); // Créer un objet HttpClient personnalisé this.client = httpclients.custoSy (). SetConnectionManager (Connemanager). HttpClients.CreateDefault ();}}Outils:
package com.darren.test.https.v45; import java.util.arraylist; import java.util.list; import java.util.map; import java.util.set; import org.apache.http.httpentity; import org.apache.http.httpruse; importation; importation; org.apache.http.namevaluepair; import org.apache.http.client.httpclient; import org.apache.http.client.entity.urlencodedFormentity; import org.apache.http.client.methods.httpget; import; org.apache.http.client.methods.httppost; import org.apache.http.client.methodsage.httprequestbase; import org.apache.http.mesage.basicNamevaluepair; Import org.apache.http.util.entityUtiles; Classique publique Default_Charset = "UTF-8"; public static String DoPost (httpclient httpclient, string url, map <string, string> paramheader, map <string> parambody) lève exception {return doPost (httpclient, url, paramheader, parambody, defaun_harket);} string dopost stand Map <string, string> paramheader, map <string, string> parambody, String Charset) lève une exception {string result = null; httppost httppost = new httppost (url); setheader (httppost, paramhener); setbody (httppost, parambody, chasset); httpresponse réponse = httpcl ! = null) {httpentity resentity = réponse.gentity (); if (resentity! = null) {result = entityUtils.tostring (Resentity, charset);}} return result;} public stating string doget (httpclient httpclient, string url, map <string, string> paramheader, map DoGet (httpClient, URL, paramheadher, parambody, default_charset);} public static static doget (httpclient httpclient, string url, map <string, string> paramheader, map <string> parambody, string charset) lance l'exception {string result = null; httpget httpget = new Httpget (url); sethader (httpget, paramheader); httpResponse réponse = httpclient.execute (httpget); if (réponse! = Null) {httpentity resentity = réponse.gentity (); if (Ressentity! = Null) {result = entityutiles.tostring (resentity! = Null) {result = entityutiles.tostring (resentity); result;} private static void sethEader (requette httpRequestBase, map <string, string> paramheader) {// set en-tête if (paramheader! = null) {set <string> keyset = paramheader.KeySet (); for (string key: keyset) {request.addheader (key, paramheader.get (key));}}} private static void setbody (httppost httppost, map <string, string> parambody, string charset) lance exception {// set paramètres if (parambody! = null) {list <namevaluepair> list = new ArrayList<NameValuePair>();Set<String> keySet = paramBody.keySet();for (String key : keySet) {list.add(new BasicNameValuePair(key, paramBody.get(key)));}if (list.size() > 0) {UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, charset); httppost.sentity (entité);}}}}Classe de test:
Package com.darren.test.https.v45; import java.util.hashmap; import java.util.map; import org.apache.http.client.httpclient; classe publique httpsclientTest {public static void main null; // httpclient = new httpstrustClient (). init (); httpClient = new httpsCertifiedClient (). init (); String url = "https://1.2.6.2:8011/xxx/api/getToken" Map<String, String> paramHeader = new HashMap<>();paramHeader.put("Accept", "application/xml");Map<String, String> paramBody = new HashMap<>();paramBody.put("client_id", "[email protected]");paramBody.put("client_secret", "P@ssword_1");String result = HttpsClientUtil.dopost (httpclient, url, paramheader, parambody); // string result = httpsClientUtil.doget (httpsclient, url, null, null); System.out.println (résultat);}}résultat:
<? xml version = "1.0" Encoding = "utf-8"?> <Token> rxitf9 // 7nxwxjs2cjijyhltvzunvmzxxeqtgn0u07sc9ysjeibpqte3hcjulskoxpeUyguveyi9jv7 / wi klrzxykc3ospatsm0kcbcKPHU0TB2CN / nfzv9fmlueowfbdyz + n0seii9k + 0gp7920dfencn17wujvmc0u2jwvm5fa jqkmilwodxz6a0dq + d7dqdjwvcwxbvj2ilhyib3pr805vppmi9atxrvako0oda006wejfofcgyg5p70wpj5rbl85v FY9WCVKD1R7J6NVJHXGH2GNIMHKJEJORMJDXW2GKIUSIWSELI / XPSWAO7 / CTWNWTNCTGK8PX2ZUB0ZFA == </ Token>
2. HttpurlConnection
@ControllerPublic class ResfulAction {@Autowired Private UserService UserService; // modifier @RequestMapping (value = "put / {param}", méthode = requestMethod.put) public @ResponseBody String put (@pathvariable String Param) {return "put:" + param;} // ajouter @requestmapping (value = "post /}", méthode = ajout @requestmapping (value = "post /}", méthode = ajout @requestmapping (value = "post /}", méthode = ajout @requestmapping (value = "post /}", méthode = ajout de la méthode = RequestMethod.post) public @ResponseBody String Post (@pathvariable String Param, String id, name string) {System.out.println ("id:" + id); System.out.println ("name:" + name); @ResponseBody String Delete (@Pathvariable String Param) {return "Delete:" + Param;} // find @RequestMapping (value = "get / {param}", méthode = requestMethod.get) public @ResponseBody String get (@pathvariable String Param) {return "get:" + Param;} // httpurlconnex @RequestMapping (value = "DealCon / {param}") public @ResponseBody String dealCon (@Pathvariable String param) {try {String url = "http: // localhost: 8080 / tao-manager-web /"; url + = (param + "/ xxx" httpconnection = (httpurlconnection) restServiceUrl .OpenConnection (); // param entrez en bascule et convertissez-le pour obtenir le post delete put httpconnection.setRequestMethod (param.touppercase ()); // httpconnection.setrestProperty ("accepter", "application / json"); if ("post" .equals (param)) {// Ouvrez le commutateur de sortie httpconnection.setDoOutput (true); // httpconnection.setDoInput (true); // passer la chaîne de paramètre Input = "& id =" + urlencoder.encode (ABC "," utf-8 "); entrée + =" & name = "+" Urlencoder.encode ("AhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhH hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh httpconnection.getOutputStream (); outputStream.write (input.getBytes ()); outputStream.flush ();} if (httpconnection.getResponSECODE ()! = 200) {Throw New RuntimeException ("HTTP GET DEMANDE REMECKET avec le code d'erreur:" + httpconnection.getResponSECODE ();} Bufferreder ResponseBuffer = new BufferedReader (new InputStreamReader ((httpConnection.getInputStream ()))); String output; System.out.println ("output from Server: / n"); while ((outputBublingBuffer.Readline ())! = null) {System.out.println (output);} (MalformEdUrlexception e) {e.printStackTrace ();} catch (ioException e) {e.printStackTrace ();} return "Success";}}3. Restemplate de Spring
Springmvc.xml ajouté
<! - Configurer RestTemplate -> <! - Http Client Factory -> <bean id = "httpclientfactory"> <propriété name = "connectTimeout" value = "10000" /> <propriété name = "readtimeout" value = "10000" /> </ bean </ban>
contrôleur
@ControllerPublic classe RestTemplateAction {@autowired private resttemplate Template; @RequestMapping ("resttem") public @ResponseBody user resttem (string méthode) {user user = null; // find if ("get" .equals (method)) {user = template.getForObject ( "http: // localhost: 8080 / tao-manager-web / get / {id}", user.class, "wuwuwuwu"); // la différence entre getForEntity et getForObject est que vous pouvez obtenir la valeur de retour et le statut, les informations d'en-tête, la réponse <utilisateur> re = template. getForEntity ("http: // localhost: 8080 / tao-manager-web / get / {id}", user.class, "wuwuwuwuwuwu"); system.out.println (re.getStaturScode ()); System.out.println (re.getBody (). ("post".equals(method)) {HttpHeaders headers = new HttpHeaders();headers.add("X-Auth-Token", UUID.randomUUID().toString());MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>();postParameters.add("id", "Ahhhhh"); postParameters.add ("name", "version partielle"); httpentity <multivalUeMap <string, string >> requestEntity = new httpentity <multivalUeMap <string, string >> (postParameters, headers); user = template.postforObject ( "http: // localhost: 8080 / tao-manager-web / post / aaa", requestEntity, user.class); // delete} else if ("delete" .equals (méthode))) {template.delete ("http: // localhost: 8080 / tao-manager-web / delete / {id}", "aaa"); // modifier} else if ("put" .equals (méthode))) {template.put ("http: // localhost: 8080 / tao-manager-web / put / {id}", null, "bbb");} return utilisateur;}}Ce qui précède est l'intégralité du contenu de cet article sur la discussion brièvement de la façon dont Java appelle l'interface API RESTFul. J'espère que ce sera utile à tout le monde. Les amis intéressés peuvent continuer à se référer à d'autres sujets liés à Java sur ce site. S'il y a des lacunes, veuillez laisser un message pour le signaler. Merci vos amis pour votre soutien pour ce site!