Resumen: Recientemente, existe un requisito para proporcionar a los clientes algunas interfaces API RESTful. QA usa Postman para las pruebas, pero la interfaz de prueba de Postman es similar pero no lo mismo que Java Llamadas. Así que quiero escribir un programa para probar la interfaz API RESTful por mí mismo. Dado que usa HTTPS, también necesito considerar el procesamiento de HTTPS. Como usé Java para llamar a la interfaz RESTFUL por primera vez, todavía necesito estudiarla, por lo que naturalmente consulté información.
Análisis: Este problema es diferente de las llamadas entre módulos. Por ejemplo, tengo dos módulos, extremo frontal y en el extremo posterior, el extremo frontal proporciona visualización frontal y Back End proporciona soporte de datos. He utilizado Hession para registrar los servicios proporcionados por Back End como servicios remotos. En la parte delantera, este servicio remoto se puede ajustar directamente a la interfaz de back -end a través de este tipo de servicio remoto. Pero esto no es un problema para que una empresa use cuando su propio proyecto está altamente acoplado. Sin embargo, si registra dicho servicio remoto con los clientes, parece no bueno y el acoplamiento es demasiado alto. Entonces considero usar el siguiente método.
1. Httpclient
Todos pueden estar familiarizados con HttpClient, pero no están familiarizados con él. Está familiarizado con él porque puede llamar de forma remota, por ejemplo, solicitar una URL y luego obtener el estado de retorno y devolver la información en la respuesta. Sin embargo, hoy estoy hablando de eso un poco más complicado, porque el tema de hoy es HTTPS, que implica el tema de los certificados o la autenticación del usuario.
Después de confirmar que con HTTPClient, busqué información relevante y descubrí que la nueva versión de HttpClient es diferente de la versión anterior, y es compatible con la versión anterior, pero ya no se recomienda que se use la versión anterior. Muchos métodos o clases se han marcado como anticuados. Hoy usaremos la versión anterior 4.2 y la última versión 4.5.3 para escribir el código respectivamente.
Versión anterior 4.2
Necesidad de certificación
El uso de la autenticación del certificado se selecciona durante la fase de preparación del certificado
paquete com.darren.test.https.v42; import java.io.file; import java.io.fileInputStream; import java.security.keystore; importar org.apache.http.conn.ssl.sslsocketfactory; La clase pública httpsCertifiedClient extiende httpsClient {public httpsCertifiedClient () {} @Override public void PrepareCertificate () lanza la excepción {// Obtener la biblioteca de teclas Keystore Truststore = KeyStore.getInstance (KeyStore.getDefaultType ()); FileInputStream Input = new FileInputStream (nuevo archivo ("c: /users/zhda6001/downloads/software/xxx.keystore")); // FileInputStream Input = new FileInputStream (nuevo archivo ("c: /users/zhda6001/downloads/xxx.keystore")); // Contraseña de la biblioteca de teclas TrustStore.load (InSteam, "Password" .ToCarArray ()); // registra la biblioteca de clave this.socketFactory = new SSLSocketFactory (confianza); // No verifique el nombre de dominio SocketFactory.SetHostNameVerifier (SSLSocketFactory.how_all_hostname_verifier); }}Omitir la certificación
La opción de omitir la autenticación durante la fase de preparación del certificado es
paquete 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; import javax.net.ssl.x509TrustManager; importar org.apache.http.conn.ssl.sslsocketfactory; La clase pública httpStrustClient extiende httpsClient {public httpStrustClient () {} @Override public void prepareCertificate () lanza excepción {// omitir verificación de certificado sslContext ctx = sslContext.getInstance ("tls"); X509TrustManager tm = new X509TrustManager () {@Override public void checkClientTrusted (x509Certificate [] cadena, cadena authtype) lanza certificateException {} @Override public void checkServerTRusted (x509Certificate [] cadena, string authType) lanza certificado de certificado {{} @overRusted X509Certificate [] getacceptedissuers () {return null; }}; // Establecer en el certificado de confianza CTX.init (NULL, New TrustManager [] {TM}, NULL); // Coloque la fábrica SSL Socket y configure para no verificar el nombre del host esto.socketFactory = new SSLSocketFactory (CTX, SSLSocketFactory. Alllow_all_hostname_verifier); }}Resumir
Ahora se encuentra que ambas clases heredan la misma clase HttpsClient, y HttpsClient hereda la clase DeFaUsTHTTPClient. Se puede encontrar que el patrón de método de plantilla se usa aquí.
paquete com.darren.test.https.v42; importar org.apache.http.conn.clientConnectionManager; importar org.apache.http.conn.scheme.scheme; importar org.apache.http.conn.ssl.sslsocketfactory; importar org.apache.http.impl.client.defaulthttpClient; public abstract Class httpsClient extiende defaulthttpClient {protegido sslsocketfactory socketFactory; / ** * Inicializar httpsClient * * @return Devuelve la instancia actual * @throws Exception */ public HttpsClient Init () lanza la excepción {this.prepareCertificate (); this.regist (); devolver esto; } / ** * Preparar verificación de certificado * * @throws Exception * / public abstract void PrepareCertificate () lanza la excepción; / *** Registro de protocolo y puerto, este método también se puede reescribir mediante subclases*/ Protected Void Regist () {ClientConnectionManager ccm = this.getConnectionManager (); Schemeregistry sr = ccm.getSchemeregistry (); Sr.register (nuevo esquema ("https", 443, socketFactory)); }} A continuación se muestra la clase de herramientas
paquete com.darren.test.https.v42; import java.util.arrayList; import java.util.list; import java.util.map; import java.util.set; importar org.apache.http.httpentity; importar org.apache.http.httpresponse; importar org.apache.http.nameValuePair; importar org.apache.http.client.entity.urlencodedformentity; importar org.apache.http.client.methods.httpget; importar org.apache.http.client.methods.httppost; importar org.apache.http.client.methods.httprequestbase; importar org.apache.http.message.BasicNameValuePair; importar org.apache.http.util.entityutils; clase pública httpsClientUtil {private static final string default_charset = "utf-8"; public static string dopost (httpsclient httpsclient, string url, map <string, string> paramheader, map <string, string> paramBody) lanza la excepción {return dopost (httpsclient, url, paramheader, parambody, default_charset); } public static string dopost (httpsclient httpsclient, string url, map <string> paramheader, map <string> parambody, string charset) lanza la excepción {string result = null; Httppost httppost = new httppost (url); Setheader (httppost, paramheader); setBody (httppost, parambody, charset); Respuesta httpResponse = httpsclient.execute (httppost); if (resentity! = null) {httpentity resentity = respuesta.getEntity (); if (resentity! = null) {result = entityUtil.ToString (resentity, charset); }} Resultado de retorno; } public static string deget (httpsClient httpsClient, string url, map <string, string> paramheader, map <string> paramBody) lanza la excepción {return doget (httpsclient, url, paramheader, parambody, default_charset); } public static string deget (httpsClient httpsClient, string url, map <string, string> paramheader, map <string> paramBody, string charset) lanza la excepción {string result = null; Httpget httpget = new httpget (url); setheader (httpget, paramheader); HttpResponse respuesta = httpsclient.execute (httpget); if (respuesta! = null) {httpentity resentity = respuesta.getEntity (); if (resentity! = null) {result = entityUtil.ToString (resentity, charset); }} Resultado de retorno; } private static void setheader (httprequestbase solicitud, map <string, string> paramheader) {// set header if (paramheader! = null) {set <tring> keySet = paramheader.keyset (); for (tecla de cadena: keySet) {request.addHeader (key, paramheader.get (key)); }}} private static void setBody (httppost httppost, map <string, string> paramBody, string charset) lanza excepción {// establece el parámetro if (parambody! = null) {list <nameValuePair> list = new ArrayList <nameValuePair> (); Establecer <String> keySet = paramBody.KeySet (); for (clave de cadena: keySet) {list.add (new BasicNameValuePair (Key, ParamBody.get (Key))); } if (list.size ()> 0) {urlencodedformentity entity = new URLEncodedFormentity (list, Charset); httppost.setEntity (entidad); }}}} Luego está la clase de prueba:
paquete com.darren.test.https.v42; import java.util.hashmap; import java.util.map; clase pública httpsClientTest {public static void main (string [] args) lanza la excepción {httpsclient httpsclient = null; httpsClient = new httpStrustClient (). init (); // httpsclient = new httpsCertifiedClient (). init (); String url = "https://1.2.6.2:8011/xxx/api/gettoken"; // String url = "https://1.2.6.2:8011/xxx/api/gethealth"; MAP <String, String> ParamHeader = new HashMap <> (); //paramheader.put("Content-type "," Application/Json "); paramheader.put ("aceptar", "aplicación/xml"); Map <string, string> paramBody = new HashMap <> (); parambody.put ("client_id", "[email protected]"); parambody.put ("client_secret", "p@ssword_1"); Resultado de cadena = httpsClientUtil.dopost (httpsclient, url, paramheader, parambody); // string result = httpsClientUtil.doget (httpsclient, url, null, null); System.out.println (resultado); }} Información de devolución:
<? xml versión = "1.0" encoding = "utf-8"?>
<Token> JKF8RL0SW+SKKFLJ8RBKI5HP1BEQK8PRCUTZPPBINQMYKRMXY1KWCJMCFT191ZPP88VV1AGHW8OYNWJEYS 0AXPLUGAX89EJCOWNBIKCC1UVFYESXHLKTCJQYUFIVJEVHREQXJPHNCLQYWP+XSE5OD9X8VKFKK7INNTMRZQK7YBTZ /E3U7GSWM/5CVAHFL6O9REQ9CWPXAVZNOHYVNXSOHSZDO+BXATXXA1XPEDLY/8H/UAP4N4DLZDJJ3B8T1XH+CRRIOM OPXF7C5WKHHTOKEOEXW+XOPQKKSX5CKWWJPPUGIIFWF/PAQWG+JUOSVT7QGDPV8PMWJ9DWEWJTDXGUDG == </token>
Nueva versión 4.5.3
Necesidad de certificación
paquete com.darren.test.https.v45; import java.io.file; import java.io.fileInputStream; import java.security.keystore; import javax.net.ssl.sslcontext; importar org.apache.http.conn.ssl.sslconnectionsockyFactory; importar org.apache.http.conn.ssl.sslconnectionsockyFactory; importar org.apache.http.conn.ssl.trustselfsignedStrategy; importar org.apache.http.ssl.sslcontexts; La clase pública httpsCertifiedClient extiende httpsClient {public httpsCertifiedClient () {} @Override public void PrepareCertificate () lanza la excepción {// Obtener la biblioteca de teclas Keystore Truststore = KeyStore.getInstance (KeyStore.getDefaultType ()); FileInputStream Institream = nuevo FileInputStream (nuevo archivo ("c: /users/zhda6001/downloads/software/xxx.keystore")); // fileInputStream Insteam = new FileInputStream (nuevo archivo ("c: /users/zhda6001/downloads/xxx.keystore")); intente {// contraseña de la biblioteca de teclas de fideicomiso. } finalmente {enterTream.close (); } SslContext sslContext = sslContexts.custom (). LoadTrustMaterial (TrustStore, TrustSelfSignedStategy.Instance) .Build (); this.connectionsocketFactory = new SSLConnectionsocketFactory (SSLContext); }}Omitir la certificación
paquete 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; import javax.net.ssl.x509TrustManager; importar org.apache.http.conn.ssl.sslconnectionsockyFactory; La clase pública httpStrustClient extiende httpsClient {public httpStrustClient () {} @Override public void prepareCertificate () lanza excepción {// omitir verificación de certificado sslContext ctx = sslContext.getInstance ("tls"); X509TrustManager tm = new X509TrustManager () {@Override public void checkClientTrusted (x509Certificate [] cadena, cadena authtype) lanza certificateException {} @Override public void checkServerTRusted (x509Certificate [] cadena, string authType) lanza certificado de certificado {{} @overRusted X509Certificate [] getacceptedissuers () {return null; }}; // Establecer en un certificado de confianza CTX.init (NULL, New TrustManager [] {TM}, NULL); this.connectionsocketFactory = new SSLConnectionsockEdFactory (CTX); }}Resumir
paquete com.darren.test.https.v45; importar org.apache.http.config.registry; importar org.apache.http.config.registryBuilder; importar org.apache.http.conn.socket.connectionsockFactory; importar org.apache.http.conn.socket.PlainConnectionSockyFactory; importar org.apache.http.impl.client.ccloseablehttpclient; importar org.apache.http.impl.client.httpclientBuilder; importar org.apache.http.impl.client.httpclients; importar org.apache.http.impl.conn.poolinghttpClientConnectionManager; public abstract Class httpsClient extiende httpclientBuilder {private cerrableHttpClient Client; Conexión protegida de ConexyFactory ConnectionSockyFactory; / ** * Inicializar httpsClient * * @return Devuelve la instancia actual * @throws Exception */ public ClosableHttpClient Init () lanza la excepción {this.prepareCertificate (); this.regist (); devolver esto.client; } / ** * Preparar verificación de certificado * * @throws Exception * / public abstract void PrepareCertificate () lanza la excepción; /** * Register protocol and port, this method can also be rewritten by subclasses*/ protected void regist() { // Set the object corresponding to protocol http and https that handles socket link factory Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionsocketFactory.instance) .register ("https", this.connectionsocketFactory) .Build (); PoolinghttpClientConnectionManager Connmanager = new PoolingHttpClientConnectionManager (SocketFactoryRegistry); Httpclients.custom (). SetConnectionManager (connmanager); // Cree un objeto HttpClient personalizado this.client = httpclients.custom (). SetConnectionManager (connmanager) .Build (); // clienthttpclient cliente = httpclients.createDefault (); }} Herramientas:
paquete com.darren.test.https.v45; import java.util.arrayList; import java.util.list; import java.util.map; import java.util.set; importar org.apache.http.httpentity; importar org.apache.http.httpresponse; importar org.apache.http.nameValuePair; importar org.apache.http.client.httpclient; importar org.apache.http.client.entity.urlencodedformentity; importar org.apache.http.client.methods.httpget; importar org.apache.http.client.methods.httppost; importar org.apache.http.client.methods.httprequestbase; importar org.apache.http.message.BasicNameValuePair; importar org.apache.http.util.entityutils; clase pública httpsClientUtil {private static final string default_charset = "utf-8"; public static string dopost (httpclient httpclient, string url, map <string, string> paramheader, map <string, string> paramBody) lanza la excepción {return dopost (httpclient, url, paramheader, parambody, default_charset); } public static string dopost (httpClient httpclient, string url, map <string, string> paramheader, map <string> parambody, string charset) lanza la excepción {string dultin = null; Httppost httppost = new httppost (url); Setheader (httppost, paramheader); setBody (httppost, parambody, charset); HttpResponse respuesta = httpclient.execute (httppost); if (resentity! = null) {httpentity resentity = respuesta.getEntity (); if (resentity! = null) {result = entityUtil.ToString (resentity, charset); }} Resultado de retorno; } public static string dogget (httpclient httpclient, string url, map <string> paramheader, map <string> paramBody) lanza la excepción {return doget (httpclient, url, paramheader, parambody, default_charset); } public static string dogget (httpclient httpclient, string url, map <string, string> paramheader, map <string> paramBody, string charset) lanza la excepción {string dult = null; Httpget httpget = new httpget (url); setheader (httpget, paramheader); HttpResponse respuesta = httpclient.execute (httpget); if (respuesta! = null) {httpentity resentity = respuesta.getEntity (); if (resentity! = null) {result = entityUtil.ToString (resentity, charset); }} Resultado de retorno; } private static void setheader (httprequestbase solicitud, map <string, string> paramheader) {// set header if (paramheader! = null) {set <tring> keySet = paramheader.keyset (); for (tecla de cadena: keySet) {request.addHeader (key, paramheader.get (key)); }}} private static void setBody (httppost httppost, map <string, string> paramBody, string charset) lanza excepción {// establece el parámetro if (parambody! = null) {list <nameValuePair> list = new ArrayList <nameValuePair> (); Establecer <String> keySet = paramBody.KeySet (); for (clave de cadena: keySet) {list.add (new BasicNameValuePair (Key, ParamBody.get (Key))); } if (list.size ()> 0) {urlencodedformentity entity = new URLEncodedFormentity (list, Charset); httppost.setEntity (entidad); }}}}}} Clase de prueba:
paquete com.darren.test.https.v45; import java.util.hashmap; import java.util.map; importar org.apache.http.client.httpclient; clase pública httpsClientTest {public static void main (string [] args) lanza la excepción {httpclient httpclient = null; // httpClient = new httpStrustClient (). init (); httpClient = new httpsCertifiedClient (). init (); String url = "https://1.2.6.2:8011/xxx/api/gettoken"; // String url = "https://1.2.6.2:8011/xxx/api/gethealth"; MAP <String, String> ParamHeader = new HashMap <> (); paramheader.put ("aceptar", "aplicación/xml"); Map <string, string> paramBody = new HashMap <> (); parambody.put ("client_id", "[email protected]"); parambody.put ("client_secret", "p@ssword_1"); Resultado de cadena = httpsClientUtil.dopost (httpclient, url, paramheader, parambody); // string result = httpsClientUtil.doget (httpsclient, url, null, null); System.out.println (resultado); }} resultado:
<? xml versión = "1.0" encoding = "utf-8"?>
<Token> RXITF9 // 7nxWXJS2CJIJYHLTVZUNVMZXXEQTGN0U07SC9YSJEIBPQTE3HCJULSKOXPEUYGUVEY9JV7/WI klrzxykc3SospatsM0kcbckphu0tb2cn/nfzv9fmlueowfbdyz+n0seii9k+0gp7920dfencn17wujvmc0u2jwvm5fa jqkmilwodxz6a0dq+d7dqdjwvcwxbvj2ilhyib3pr805vppmi9atxrvako0oda006wejfofcgyg5p70wpj5rrrbbl85v FY9WCVKD1R7J6NVJHXGH2GNIMHKJEJORMJDXW2GKIUSIWSELI/XPSWAO7/CTWNWTNCTGK8PX2ZUB0ZFA == </Token>
2. Httpurlconnection
3. Spring's RestTemplate
Otros métodos se complementarán más tarde
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.