打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Java 调用Restful API接口的几种方式

摘要:最近有一个需求,为客户提供一些Restful API 接口,QA使用postman进行测试,但是postman的测试接口与java调用的相似但并不相同,于是想自己写一个程序去测试Restful API接口,由于使用的是HTTPS,所以还要考虑到对于HTTPS的处理。由于我也是首次使用Java调用restful接口,所以还要研究一番,自然也是查阅了一些资料。

分析:这个问题与模块之间的调用不同,比如我有两个模块front end 和back end,front end提供前台展示,back end提供数据支持。之前使用过Hession去把back end提供的服务注册成远程服务,在front end端可以通过这种远程服务直接调到back end的接口。但这对于一个公司自己的一个项目耦合性比较高的情况下使用,没有问题。但是如果给客户注册这种远程服务,似乎不太好,耦合性太高。所以就考虑用一下方式进行处理。


一、HttpClient


HttpClient大家也许比较熟悉但又比较陌生,熟悉是知道他可以远程调用比如请求一个URL,然后在response里获取到返回状态和返回信息,但是今天讲的稍微复杂一点,因为今天的主题是HTTPS,这个牵涉到证书或用户认证的问题。

确定使用HttpClient之后,查询相关资料,发现HttpClient的新版本与老版本不同,随然兼容老版本,但已经不提倡老版本是使用方式,很多都已经标记为过时的方法或类。今天就分别使用老版本4.2和最新版本4.5.3来写代码。


老版本4.2


需要认证



在准备证书阶段选择的是使用证书认证

  1. package com.darren.test.https.v42;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.security.KeyStore;
  5. import org.apache.http.conn.ssl.SSLSocketFactory;
  6. public class HTTPSCertifiedClient extends HTTPSClient {
  7. public HTTPSCertifiedClient() {
  8. }
  9. @Override
  10. public void prepareCertificate() throws Exception {
  11. // 获得密匙库
  12. KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
  13. FileInputStream instream = new FileInputStream(
  14. new File("C:/Users/zhda6001/Downloads/software/xxx.keystore"));
  15. // FileInputStream instream = new FileInputStream(new File("C:/Users/zhda6001/Downloads/xxx.keystore"));
  16. // 密匙库的密码
  17. trustStore.load(instream, "password".toCharArray());
  18. // 注册密匙库
  19. this.socketFactory = new SSLSocketFactory(trustStore);
  20. // 不校验域名
  21. socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
  22. }
  23. }


跳过认证


在准备证书阶段选择的是跳过认证

  1. package com.darren.test.https.v42;
  2. import java.security.cert.CertificateException;
  3. import java.security.cert.X509Certificate;
  4. import javax.net.ssl.SSLContext;
  5. import javax.net.ssl.TrustManager;
  6. import javax.net.ssl.X509TrustManager;
  7. import org.apache.http.conn.ssl.SSLSocketFactory;
  8. public class HTTPSTrustClient extends HTTPSClient {
  9. public HTTPSTrustClient() {
  10. }
  11. @Override
  12. public void prepareCertificate() throws Exception {
  13. // 跳过证书验证
  14. SSLContext ctx = SSLContext.getInstance("TLS");
  15. X509TrustManager tm = new X509TrustManager() {
  16. @Override
  17. public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
  18. }
  19. @Override
  20. public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
  21. }
  22. @Override
  23. public X509Certificate[] getAcceptedIssuers() {
  24. return null;
  25. }
  26. };
  27. // 设置成已信任的证书
  28. ctx.init(null, new TrustManager[] { tm }, null);
  29. // 穿件SSL socket 工厂,并且设置不检查host名称
  30. this.socketFactory = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
  31. }
  32. }


总结


现在发现这两个类都继承了同一个类HTTPSClient,并且HTTPSClient继承了DefaultHttpClient类,可以发现,这里使用了模板方法模式。

  1. package com.darren.test.https.v42;
  2. import org.apache.http.conn.ClientConnectionManager;
  3. import org.apache.http.conn.scheme.Scheme;
  4. import org.apache.http.conn.scheme.SchemeRegistry;
  5. import org.apache.http.conn.ssl.SSLSocketFactory;
  6. import org.apache.http.impl.client.DefaultHttpClient;
  7. public abstract class HTTPSClient extends DefaultHttpClient {
  8. protected SSLSocketFactory socketFactory;
  9. /**
  10. * 初始化HTTPSClient
  11. *
  12. * @return 返回当前实例
  13. * @throws Exception
  14. */
  15. public HTTPSClient init() throws Exception {
  16. this.prepareCertificate();
  17. this.regist();
  18. return this;
  19. }
  20. /**
  21. * 准备证书验证
  22. *
  23. * @throws Exception
  24. */
  25. public abstract void prepareCertificate() throws Exception;
  26. /**
  27. * 注册协议和端口, 此方法也可以被子类重写
  28. */
  29. protected void regist() {
  30. ClientConnectionManager ccm = this.getConnectionManager();
  31. SchemeRegistry sr = ccm.getSchemeRegistry();
  32. sr.register(new Scheme("https", 443, socketFactory));
  33. }
  34. }

下边是工具类

  1. package com.darren.test.https.v42;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.Map;
  5. import java.util.Set;
  6. import org.apache.http.HttpEntity;
  7. import org.apache.http.HttpResponse;
  8. import org.apache.http.NameValuePair;
  9. import org.apache.http.client.entity.UrlEncodedFormEntity;
  10. import org.apache.http.client.methods.HttpGet;
  11. import org.apache.http.client.methods.HttpPost;
  12. import org.apache.http.client.methods.HttpRequestBase;
  13. import org.apache.http.message.BasicNameValuePair;
  14. import org.apache.http.util.EntityUtils;
  15. public class HTTPSClientUtil {
  16. private static final String DEFAULT_CHARSET = "UTF-8";
  17. public static String doPost(HTTPSClient httpsClient, String url, Map<String, String> paramHeader,
  18. Map<String, String> paramBody) throws Exception {
  19. return doPost(httpsClient, url, paramHeader, paramBody, DEFAULT_CHARSET);
  20. }
  21. public static String doPost(HTTPSClient httpsClient, String url, Map<String, String> paramHeader,
  22. Map<String, String> paramBody, String charset) throws Exception {
  23. String result = null;
  24. HttpPost httpPost = new HttpPost(url);
  25. setHeader(httpPost, paramHeader);
  26. setBody(httpPost, paramBody, charset);
  27. HttpResponse response = httpsClient.execute(httpPost);
  28. if (response != null) {
  29. HttpEntity resEntity = response.getEntity();
  30. if (resEntity != null) {
  31. result = EntityUtils.toString(resEntity, charset);
  32. }
  33. }
  34. return result;
  35. }
  36. public static String doGet(HTTPSClient httpsClient, String url, Map<String, String> paramHeader,
  37. Map<String, String> paramBody) throws Exception {
  38. return doGet(httpsClient, url, paramHeader, paramBody, DEFAULT_CHARSET);
  39. }
  40. public static String doGet(HTTPSClient httpsClient, String url, Map<String, String> paramHeader,
  41. Map<String, String> paramBody, String charset) throws Exception {
  42. String result = null;
  43. HttpGet httpGet = new HttpGet(url);
  44. setHeader(httpGet, paramHeader);
  45. HttpResponse response = httpsClient.execute(httpGet);
  46. if (response != null) {
  47. HttpEntity resEntity = response.getEntity();
  48. if (resEntity != null) {
  49. result = EntityUtils.toString(resEntity, charset);
  50. }
  51. }
  52. return result;
  53. }
  54. private static void setHeader(HttpRequestBase request, Map<String, String> paramHeader) {
  55. // 设置Header
  56. if (paramHeader != null) {
  57. Set<String> keySet = paramHeader.keySet();
  58. for (String key : keySet) {
  59. request.addHeader(key, paramHeader.get(key));
  60. }
  61. }
  62. }
  63. private static void setBody(HttpPost httpPost, Map<String, String> paramBody, String charset) throws Exception {
  64. // 设置参数
  65. if (paramBody != null) {
  66. List<NameValuePair> list = new ArrayList<NameValuePair>();
  67. Set<String> keySet = paramBody.keySet();
  68. for (String key : keySet) {
  69. list.add(new BasicNameValuePair(key, paramBody.get(key)));
  70. }
  71. if (list.size() > 0) {
  72. UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, charset);
  73. httpPost.setEntity(entity);
  74. }
  75. }
  76. }
  77. }

然后是测试类:

  1. package com.darren.test.https.v42;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. public class HTTPSClientTest {
  5. public static void main(String[] args) throws Exception {
  6. HTTPSClient httpsClient = null;
  7. httpsClient = new HTTPSTrustClient().init();
  8. //httpsClient = new HTTPSCertifiedClient().init();
  9. String url = "https://1.2.6.2:8011/xxx/api/getToken";
  10. //String url = "https://1.2.6.2:8011/xxx/api/getHealth";
  11. Map<String, String> paramHeader = new HashMap<>();
  12. //paramHeader.put("Content-Type", "application/json");
  13. paramHeader.put("Accept", "application/xml");
  14. Map<String, String> paramBody = new HashMap<>();
  15. paramBody.put("client_id", "ankur.tandon.ap@xxx.com");
  16. paramBody.put("client_secret", "P@ssword_1");
  17. String result = HTTPSClientUtil.doPost(httpsClient, url, paramHeader, paramBody);
  18. //String result = HTTPSClientUtil.doGet(httpsClient, url, null, null);
  19. System.out.println(result);
  20. }
  21. }

返回信息:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <token>jkf8RL0sw+Skkflj8RbKI5hP1bEQK8PrCuTZPpBINqMYKRMxY1kWCjmCfT191Zpp88VV1aGHW8oYNWjEYS0axpLuGAX89ejCoWNbikCc1UvfyesXHLktcJqyUFiVjevhrEQxJPHncLQYWP+Xse5oD9X8vKFKk7InNTMRzQK7YBTZ/e3U7gswM/5cvAHFl6o9rEq9cWPXavZNohyvnXsohSzDo+BXAtXxa1xpEDLy/8h/UaP4n4dlZDJJ3B8t1Xh+CRRIoMOPxf7c5wKhHtOkEOeXW+xoPQKKSx5CKWwJpPuGIIFWF/PaqWg+JUOsVT7QGdPv8PMWJ9DwEwjTdxguDg==</token>



新版本4.5.3


需要认证


  1. package com.darren.test.https.v45;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.security.KeyStore;
  5. import javax.net.ssl.SSLContext;
  6. import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
  7. import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
  8. import org.apache.http.ssl.SSLContexts;
  9. public class HTTPSCertifiedClient extends HTTPSClient {
  10. public HTTPSCertifiedClient() {
  11. }
  12. @Override
  13. public void prepareCertificate() throws Exception {
  14. // 获得密匙库
  15. KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
  16. FileInputStream instream = new FileInputStream(
  17. new File("C:/Users/zhda6001/Downloads/software/xxx.keystore"));
  18. // FileInputStream instream = new FileInputStream(new File("C:/Users/zhda6001/Downloads/xxx.keystore"));
  19. try {
  20. // 密匙库的密码
  21. trustStore.load(instream, "password".toCharArray());
  22. } finally {
  23. instream.close();
  24. }
  25. SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, TrustSelfSignedStrategy.INSTANCE)
  26. .build();
  27. this.connectionSocketFactory = new SSLConnectionSocketFactory(sslcontext);
  28. }
  29. }


跳过认证


  1. package com.darren.test.https.v45;
  2. import java.security.cert.CertificateException;
  3. import java.security.cert.X509Certificate;
  4. import javax.net.ssl.SSLContext;
  5. import javax.net.ssl.TrustManager;
  6. import javax.net.ssl.X509TrustManager;
  7. import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
  8. public class HTTPSTrustClient extends HTTPSClient {
  9. public HTTPSTrustClient() {
  10. }
  11. @Override
  12. public void prepareCertificate() throws Exception {
  13. // 跳过证书验证
  14. SSLContext ctx = SSLContext.getInstance("TLS");
  15. X509TrustManager tm = new X509TrustManager() {
  16. @Override
  17. public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
  18. }
  19. @Override
  20. public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
  21. }
  22. @Override
  23. public X509Certificate[] getAcceptedIssuers() {
  24. return null;
  25. }
  26. };
  27. // 设置成已信任的证书
  28. ctx.init(null, new TrustManager[] { tm }, null);
  29. this.connectionSocketFactory = new SSLConnectionSocketFactory(ctx);
  30. }
  31. }


总结


  1. package com.darren.test.https.v45;
  2. import org.apache.http.config.Registry;
  3. import org.apache.http.config.RegistryBuilder;
  4. import org.apache.http.conn.socket.ConnectionSocketFactory;
  5. import org.apache.http.conn.socket.PlainConnectionSocketFactory;
  6. import org.apache.http.impl.client.CloseableHttpClient;
  7. import org.apache.http.impl.client.HttpClientBuilder;
  8. import org.apache.http.impl.client.HttpClients;
  9. import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
  10. public abstract class HTTPSClient extends HttpClientBuilder {
  11. private CloseableHttpClient client;
  12. protected ConnectionSocketFactory connectionSocketFactory;
  13. /**
  14. * 初始化HTTPSClient
  15. *
  16. * @return 返回当前实例
  17. * @throws Exception
  18. */
  19. public CloseableHttpClient init() throws Exception {
  20. this.prepareCertificate();
  21. this.regist();
  22. return this.client;
  23. }
  24. /**
  25. * 准备证书验证
  26. *
  27. * @throws Exception
  28. */
  29. public abstract void prepareCertificate() throws Exception;
  30. /**
  31. * 注册协议和端口, 此方法也可以被子类重写
  32. */
  33. protected void regist() {
  34. // 设置协议http和https对应的处理socket链接工厂的对象
  35. Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
  36. .register("http", PlainConnectionSocketFactory.INSTANCE)
  37. .register("https", this.connectionSocketFactory)
  38. .build();
  39. PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
  40. HttpClients.custom().setConnectionManager(connManager);
  41. // 创建自定义的httpclient对象
  42. this.client = HttpClients.custom().setConnectionManager(connManager).build();
  43. // CloseableHttpClient client = HttpClients.createDefault();
  44. }
  45. }


工具类:

  1. package com.darren.test.https.v45;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.Map;
  5. import java.util.Set;
  6. import org.apache.http.HttpEntity;
  7. import org.apache.http.HttpResponse;
  8. import org.apache.http.NameValuePair;
  9. import org.apache.http.client.HttpClient;
  10. import org.apache.http.client.entity.UrlEncodedFormEntity;
  11. import org.apache.http.client.methods.HttpGet;
  12. import org.apache.http.client.methods.HttpPost;
  13. import org.apache.http.client.methods.HttpRequestBase;
  14. import org.apache.http.message.BasicNameValuePair;
  15. import org.apache.http.util.EntityUtils;
  16. public class HTTPSClientUtil {
  17. private static final String DEFAULT_CHARSET = "UTF-8";
  18. public static String doPost(HttpClient httpClient, String url, Map<String, String> paramHeader,
  19. Map<String, String> paramBody) throws Exception {
  20. return doPost(httpClient, url, paramHeader, paramBody, DEFAULT_CHARSET);
  21. }
  22. public static String doPost(HttpClient httpClient, String url, Map<String, String> paramHeader,
  23. Map<String, String> paramBody, String charset) throws Exception {
  24. String result = null;
  25. HttpPost httpPost = new HttpPost(url);
  26. setHeader(httpPost, paramHeader);
  27. setBody(httpPost, paramBody, charset);
  28. HttpResponse response = httpClient.execute(httpPost);
  29. if (response != null) {
  30. HttpEntity resEntity = response.getEntity();
  31. if (resEntity != null) {
  32. result = EntityUtils.toString(resEntity, charset);
  33. }
  34. }
  35. return result;
  36. }
  37. public static String doGet(HttpClient httpClient, String url, Map<String, String> paramHeader,
  38. Map<String, String> paramBody) throws Exception {
  39. return doGet(httpClient, url, paramHeader, paramBody, DEFAULT_CHARSET);
  40. }
  41. public static String doGet(HttpClient httpClient, String url, Map<String, String> paramHeader,
  42. Map<String, String> paramBody, String charset) throws Exception {
  43. String result = null;
  44. HttpGet httpGet = new HttpGet(url);
  45. setHeader(httpGet, paramHeader);
  46. HttpResponse response = httpClient.execute(httpGet);
  47. if (response != null) {
  48. HttpEntity resEntity = response.getEntity();
  49. if (resEntity != null) {
  50. result = EntityUtils.toString(resEntity, charset);
  51. }
  52. }
  53. return result;
  54. }
  55. private static void setHeader(HttpRequestBase request, Map<String, String> paramHeader) {
  56. // 设置Header
  57. if (paramHeader != null) {
  58. Set<String> keySet = paramHeader.keySet();
  59. for (String key : keySet) {
  60. request.addHeader(key, paramHeader.get(key));
  61. }
  62. }
  63. }
  64. private static void setBody(HttpPost httpPost, Map<String, String> paramBody, String charset) throws Exception {
  65. // 设置参数
  66. if (paramBody != null) {
  67. List<NameValuePair> list = new ArrayList<NameValuePair>();
  68. Set<String> keySet = paramBody.keySet();
  69. for (String key : keySet) {
  70. list.add(new BasicNameValuePair(key, paramBody.get(key)));
  71. }
  72. if (list.size() > 0) {
  73. UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, charset);
  74. httpPost.setEntity(entity);
  75. }
  76. }
  77. }
  78. }


测试类:

  1. package com.darren.test.https.v45;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import org.apache.http.client.HttpClient;
  5. public class HTTPSClientTest {
  6. public static void main(String[] args) throws Exception {
  7. HttpClient httpClient = null;
  8. //httpClient = new HTTPSTrustClient().init();
  9. httpClient = new HTTPSCertifiedClient().init();
  10. String url = "https://1.2.6.2:8011/xxx/api/getToken";
  11. //String url = "https://1.2.6.2:8011/xxx/api/getHealth";
  12. Map<String, String> paramHeader = new HashMap<>();
  13. paramHeader.put("Accept", "application/xml");
  14. Map<String, String> paramBody = new HashMap<>();
  15. paramBody.put("client_id", "ankur.tandon.ap@xxx.com");
  16. paramBody.put("client_secret", "P@ssword_1");
  17. String result = HTTPSClientUtil.doPost(httpClient, url, paramHeader, paramBody);
  18. //String result = HTTPSClientUtil.doGet(httpsClient, url, null, null);
  19. System.out.println(result);
  20. }
  21. }

结果:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <token>RxitF9//7NxwXJS2cjIjYhLtvzUNvMZxxEQtGN0u07sC9ysJeIbPqte3hCjULSkoXPEUYGUVeyI9jv7/WikLrzxYKc3OSpaTSM0kCbCKphu0TB2Cn/nfzv9fMLueOWFBdyz+N0sEiI9K+0Gp7920DFEncn17wUJVmC0u2jwvM5FAjQKmilwodXZ6a0Dq+D7dQDJwVcwxBvJ2ilhyIb3pr805Vppmi9atXrVAKO0ODa006wEJFOfcgyG5p70wpJ5rrBL85vfy9WCvkd1R7j6NVjhXgH2gNimHkjEJorMjdXW2gKiUsiWsELi/XPswao7/CTWNwTnctGK8PX2ZUB0ZfA==</token>



二、HttpURLConnection


三、Spring的RestTemplate


其它方式以后补充


参考:

JAVA利用HttpClient进行POST请求(HTTPS)

CloseableHttpClient加载证书来访问https网站


在准备证书阶段选择的是跳过认证
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
httpclient教程
java接入钉钉机器人实现告警通知
Redis - 存储验证码
Android Post Get(最新 HttpClient 事例)
用Java和Perl登录新浪微博
spring集成httpclient连接池配置
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服