Abstract: Recently, there is a requirement to provide customers with some Restful API interfaces. QA uses postman for testing, but the test interface of postman is similar but not the same as Java calls. So I want to write a program to test the Restful API interface by myself. Since it uses HTTPS, I also need to consider the processing of HTTPS. Since I used Java to call the restful interface for the first time, I still need to study it, so I naturally consulted some information.
Analysis: This problem is different from the calls between modules. For example, I have two modules, front end and back end, front end provides front-end display, and back end provides data support. I have used Hession to register the services provided by back end as remote services. On the front end, this remote service can be directly adjusted to the back end interface through this kind of remote service. But this is no problem for a company to use when its own project is highly coupled. However, if you register such remote service with customers, it seems not good and the coupling is too high. So I consider using the following method.
1. HttpClient
Everyone may be familiar with HttpClient but is unfamiliar with it. It is familiar with it because it can remotely call, for example, request a URL, and then get the return status and return information in the response. However, today I am talking about it a little more complicated, because today's topic is HTTPS, which involves the issue of certificates or user authentication.
After confirming that using HttpClient, I searched for relevant information and found that the new version of HttpClient is different from the old version, and is compatible with the old version, but it is no longer recommended that the old version be used. Many methods or classes have been marked as outdated. Today, we will use the old version 4.2 and the latest version 4.5.3 to write the code respectively.
Old version 4.2
Need for certification
The use of certificate authentication is selected during the certificate preparation phase
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 HTTPSCertifiedClient extends HTTPSClient { public HTTPSCertifiedClient() { } @Override public void prepareCertificate() throws Exception { // Get the key library KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); FileInputStream input = new FileInputStream( new File("C:/Users/zhda6001/Downloads/software/xxx.keystore")); // FileInputStream input = new FileInputStream(new File("C:/Users/zhda6001/Downloads/xxx.keystore")); // Password of the key library trustStore.load(instream, "password".toCharArray()); // Register the key library this.socketFactory = new SSLSocketFactory(trustStore); // Do not check the domain name socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); } }Skip the certification
The option to skip authentication during the certificate preparation phase is to
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; import javax.net.ssl.X509TrustManager; import org.apache.http.conn.ssl.SSLSocketFactory; public class HTTPSTrustClient extends HTTPSClient { public HTTPSTrustClient() { } @Override public void prepareCertificate() throws Exception { // Skip certificate verification SSLContext ctx = SSLContext.getInstance("TLS"); X509TrustManager tm = new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }; // Set to the trusted certificate ctx.init(null, new TrustManager[] { tm }, null); // Put the SSL socket factory, and set not to check the host name this.socketFactory = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); } }Summarize
Now it is found that both classes inherit the same class HTTPSClient, and HTTPSClient inherits the DefaultHttpClient class. It can be found that the template method pattern is used here.
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; import org.apache.http.impl.client.DefaultHttpClient; public abstract class HTTPSClient extends DefaultHttpClient { protected SSLSocketFactory socketFactory; /** * Initialize HTTPSClient * * @return Return the current instance* @throws Exception */ public HTTPSClient init() throws Exception { this.prepareCertificate(); this.regist(); return this; } /** * Prepare certificate verification* * @throws Exception */ public abstract void prepareCertificate() throws Exception; /** * Register protocol and port, this method can also be rewritten by subclasses*/ protected void regist() { ClientConnectionManager ccm = this.getConnectionManager(); SchemeRegistry sr = ccm.getSchemeRegistry(); sr.register(new Scheme("https", 443, socketFactory)); } } Below is the tool class
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.HttpResponse; 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.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; public class 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) throws Exception { return doPost(httpsClient, url, paramHeader, paramBody, DEFAULT_CHARSET); } public static String doPost(HTTPSClient httpsClient, String url, Map<String, String> paramHeader, Map<String, String> paramBody, String charset) throws Exception { String result = null; HttpPost httpPost = new HttpPost(url); setHeader(httpPost, paramHeader); setBody(httpPost, paramBody, charset); HttpResponse response = httpsClient.execute(httpPost); if (resEntity != null) { HttpEntity resEntity = response.getEntity(); if (resEntity != null) { result = EntityUtils.toString(resEntity, charset); } } return result; } public static String doGet(HTTPSClient httpsClient, String url, Map<String, String> paramHeader, Map<String, String> paramBody) throws Exception { return doGet(httpsClient, url, paramHeader, paramBody, DEFAULT_CHARSET); } public static String doGet(HTTPSClient httpsClient, String url, Map<String, String> paramHeader, Map<String, String> paramBody, String charset) throws Exception { String result = null; HttpGet httpGet = new HttpGet(url); setHeader(httpGet, paramHeader); HttpResponse response = httpsClient.execute(httpGet); if (response != null) { HttpEntity resEntity = response.getEntity(); if (resEntity != null) { result = EntityUtils.toString(resEntity, charset); } } return result; } private static void setHeader(HttpRequestBase request, Map<String, String> paramHeader) { // Set Header 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) throws Exception { // Set the parameter 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.setEntity(entity); } } } } Then there is the test class:
package com.darren.test.https.v42; import java.util.HashMap; import java.util.Map; public class HTTPSClientTest { public static void main(String[] args) throws Exception { 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("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(httpsClient, url, paramHeader, paramBody); //String result = HTTPSClientUtil.doGet(httpsClient, url, null, null); System.out.println(result); } } Return information:
<?xml version="1.0" encoding="utf-8"?>
<token>jkf8RL0sw+Skkflj8RbKI5hP1bEQK8PrCuTZPpBINqMYKRMxY1kWCjmCfT191Zpp88VV1aGHW8oYNWjEYS0axpLuGAX89ejCoWNbikCc1UvfyesXHLktcJqyUFiVjevhrEQxJPHncLQYWP+Xse5oD9X8vKFKk7InNTMRzQK7YBTZ /e3U7gswM/5cvAHFl6o9rEq9cWPXavZNohyvnXsohSzDo+BXAtXxa1xpEDLy/8h/UaP4n4dlZDJJ3B8t1Xh+CRRIoMOPxf7c5wKhHtOkEOeXW+xoPQKKSx5CKWwJpPuGIIFWF/PaqWg+JUOsVT7QGdPv8PMWJ9DwEwjTdxguDg==</token>
New version 4.5.3
Need for 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.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.ssl.SSLContexts; public class HTTPSCertifiedClient extends HTTPSClient { public HTTPSCertifiedClient() { } @Override public void prepareCertificate() throws Exception { // Get the key library KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); FileInputStream Instream = new FileInputStream( new File("C:/Users/zhda6001/Downloads/software/xxx.keystore")); // FileInputStream Instream = new FileInputStream(new File("C:/Users/zhda6001/Downloads/xxx.keystore")); try { // Password of the key library trustStore.load(instream, "password".toCharArray()); } finally { enterstream.close(); } SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, TrustSelfSignedStrategy.INSTANCE) .build(); this.connectionSocketFactory = new SSLConnectionSocketFactory(sslcontext); } }Skip the 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; import javax.net.ssl.X509TrustManager; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; public class HTTPSTrustClient extends HTTPSClient { public HTTPSTrustClient() { } @Override public void prepareCertificate() throws Exception { // Skip certificate verification SSLContext ctx = SSLContext.getInstance("TLS"); X509TrustManager tm = new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }; // Set to a trusted certificate ctx.init(null, new TrustManager[] { tm }, null); this.connectionSocketFactory = new SSLConnectionSocketFactory(ctx); } }Summarize
package com.darren.test.https.v45; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; public abstract class HTTPSClient extends HttpClientBuilder { private CloseableHttpClient client; protected ConnectionSocketFactory connectionSocketFactory; /** * Initialize HTTPSClient * * @return Return the current instance* @throws Exception */ public CloseableHttpClient init() throws Exception { this.prepareCertificate(); this.regist(); return this.client; } /** * Prepare certificate verification* * @throws Exception */ public abstract void prepareCertificate() throws Exception; /** * 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); // Create a custom httpclient object this.client = HttpClients.custom().setConnectionManager(connManager).build(); // CloseableHttpClient client = HttpClients.createDefault(); } } Tools:
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.HttpResponse; import 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.methods.HttpRequestBase; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; public class 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) throws Exception { return doPost(httpClient, url, paramHeader, paramBody, DEFAULT_CHARSET); } public static String doPost(HttpClient httpClient, String url, Map<String, String> paramHeader, Map<String, String> paramBody, String charset) throws Exception { String result = null; HttpPost httpPost = new HttpPost(url); setHeader(httpPost, paramHeader); setBody(httpPost, paramBody, charset); HttpResponse response = httpClient.execute(httpPost); if (resEntity != null) { HttpEntity resEntity = response.getEntity(); if (resEntity != null) { result = EntityUtils.toString(resEntity, charset); } } return result; } public static String doGet(HttpClient httpClient, String url, Map<String, String> paramHeader, Map<String, String> paramBody) throws Exception { return doGet(httpClient, url, paramHeader, paramBody, DEFAULT_CHARSET); } public static String doGet(HttpClient httpClient, String url, Map<String, String> paramHeader, Map<String, String> paramBody, String charset) throws Exception { String result = null; HttpGet httpGet = new HttpGet(url); setHeader(httpGet, paramHeader); HttpResponse response = httpClient.execute(httpGet); if (response != null) { HttpEntity resEntity = response.getEntity(); if (resEntity != null) { result = EntityUtils.toString(resEntity, charset); } } return result; } private static void setHeader(HttpRequestBase request, Map<String, String> paramHeader) { // Set Header 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) throws Exception { // Set the parameter 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.setEntity(entity); } } } } } } Test class:
package com.darren.test.https.v45; import java.util.HashMap; import java.util.Map; import org.apache.http.client.HttpClient; public class HTTPSClientTest { public static void main(String[] args) throws Exception { 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("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(result); } } result:
<?xml version="1.0" encoding="utf-8"?>
<token>RxitF9//7NxwXJS2cjIjYhLtvzUNvMZxxEQtGN0u07sC9ysJeIbPqte3hCjULSkoXPEUYGUVeyI9jv7/WikLrzxYKc3OSpaTSM0kCbCKphu0TB2Cn/nfzv9fMLueOWFBdyz+N0sEiI9K+0Gp7920DFEncn17wUJVmC0u2jwvM5FA jQKmilwodXZ6a0Dq+D7dQDJwVcwxBvJ2ilhyIb3pr805Vppmi9atXrVAKO0ODa006wEJFOfcgyG5p70wpJ5rrBL85vfy9WCvkd1R7j6NVjhXgH2gNimHkjEJorMjdXW2gKiUsiWsELi/XPswao7/CTWNwTnctGK8PX2ZUB0ZfA==</token>
2. HttpURLConnection
3. Spring's RestTemplate
Other methods will be supplemented later
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.