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 frontend and backend. Frontend provides frontend display and backend provides data support. I have used Hession to register the services provided by backend as remote services. On the frontend side, this remote service can be directly adjusted to the backend interface. 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.
Basic introduction
For the call of the Restful interface, the front-end generally uses ajax call, and the back-end can use more methods.
This time, three types are introduced:
1.HttpURLConnection implementation
2.HttpClient implementation
3. Spring's RestTemplate
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 the 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 (response != 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 parameters 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 {instream.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 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 to 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 (response != 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 parameters 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
@Controllerpublic class RestfulAction {@Autowired private UserService userService;// Modify @RequestMapping(value = "put/{param}", method = RequestMethod.PUT) public @ResponseBody String put(@PathVariable String param) {return "put:" + param;}// Add @RequestMapping(value = "post/{param}", method = RequestMethod.POST) public @ResponseBody String post(@PathVariable String param,String id,String name) {System.out.println("id:"+id);System.out.println("name:"+name);return "post:" + param;}// Delete @RequestMapping(value = "delete/{param}", method = RequestMethod.DELETE) public @ResponseBody String delete(@PathVariable String param) {return "delete:" + param;}// Find @RequestMapping(value = "get/{param}", method = RequestMethod.GET) public @ResponseBody String get(@PathVariable String param) {return "get:" + param;}// HttpURLConnection method calls the Restful interface// Call the interface @RequestMapping(value = "dealCon/{param}") public @ResponseBody String dealCon(@PathVariable String param) {try {String url = "http://localhost:8080/tao-manager-web/";url+=(param+"/xxx");URL restServiceURL = new URL(url);HttpURLConnection httpConnection = (HttpURLConnection) restServiceURL .openConnection();//param Enter lowercase and convert it to GET POST DELETE PUT httpConnection.setRequestMethod(param.toUpperCase());// httpConnection.setRequestProperty("Accept", "application/json");if("post".equals(param)){//Open the output switch httpConnection.setDoOutput(true);// httpConnection.setDoInput(true);// Pass the parameter String input = "&id="+ URLEncoder.encode("abc", "UTF-8");input+="&name="+ URLEncoder.encode("Ahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh httpConnection.getOutputStream();outputStream.write(input.getBytes());outputStream.flush();}if (httpConnection.getResponseCode() != 200) {throw new RuntimeException( "HTTP GET Request Failed with Error code : " + httpConnection.getResponseCode());}BufferedReader responseBuffer = new BufferedReader( new InputStreamReader((httpConnection.getInputStream())));String output;System.out.println("Output from Server: /n");while ((output = responseBuffer.readLine()) != null) {System.out.println(output);}httpConnection.disconnect();}catch (MalformedURLException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}return "success";}}3. Spring's RestTemplate
springmvc.xml added
<!-- Configure RestTemplate --> <!--Http client Factory --> <bean id="httpClientFactory" > <property name="connectTimeout" value="10000" /> <property name="readTimeout" value="10000" /> </bean> <!--RestTemplate --> <bean id="restTemplate"> <constructor-arg ref="httpClientFactory" /> </bean>
controller
@Controllerpublic class RestTemplateAction {@Autowired private RestTemplate template;@RequestMapping("RestTem") public @ResponseBody User RestTem(String method) {User user = null;//Find if ("get".equals(method)) {user = template.getForObject( "http://localhost:8080/tao-manager-web/get/{id}", User.class, "Wuwuwuwu");//The difference between getForEntity and getForObject is that you can get the return value and status, header information, ResponseEntity<User> re = template. getForEntity("http://localhost:8080/tao-manager-web/get/{id}", User.class, "Wuwuwuwuwuwu");System.out.println(re.getStatusCode());System.out.println(re.getBody().getUsername());//New} else if ("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", "partial version");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(method)) {template.delete("http://localhost:8080/tao-manager-web/delete/{id}","aaa");//Modify} else if ("put".equals(method)) {template.put("http://localhost:8080/tao-manager-web/put/{id}",null,"bbb");}return user;}}The above is the entire content of this article about briefly discussing the way Java calls the Restful API interface. I hope it will be helpful to everyone. Interested friends can continue to refer to other Java -related topics on this website. If there are any shortcomings, please leave a message to point it out. Thank you friends for your support for this site!