Java 调用Restful API接口的几种方式(HTTPS)

摘要:最近有一个需求,为客户提供一些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

需要认证

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

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 {
    // 获得密匙库
    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"));
    // 密匙库的密码
    trustStore.load(instream, "password".toCharArray());
    // 注册密匙库
    this.socketFactory = new SSLSocketFactory(trustStore);
    // 不校验域名
    socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
  }
}

跳过认证

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

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 {
    // 跳过证书验证
    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;
      }
    };
    // 设置成已信任的证书
    ctx.init(null, new TrustManager[] { tm }, null);
    // 穿件SSL socket 工厂,并且设置不检查host名称
    this.socketFactory = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
  }
} 

总结

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

package com.darren.test.https.v42;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
public abstract class HTTPSClient extends DefaultHttpClient {
  protected SSLSocketFactory socketFactory; 

  /**
   * 初始化HTTPSClient
   *
   * @return 返回当前实例
   * @throws Exception
   */
  public HTTPSClient init() throws Exception {
    this.prepareCertificate();
    this.regist(); 

    return this;
  }
  /**
   * 准备证书验证
   *
   * @throws Exception
   */
  public abstract void prepareCertificate() throws Exception; 

  /**
   * 注册协议和端口, 此方法也可以被子类重写
   */
  protected void regist() {
    ClientConnectionManager ccm = this.getConnectionManager();
    SchemeRegistry sr = ccm.getSchemeRegistry();
    sr.register(new Scheme("https", 443, socketFactory));
  }
}

下边是工具类

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) {
    // 设置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 {
    // 设置参数
    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);
      }
    }
  }
} 

然后是测试类:

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", "ankur.tandon.ap@xxx.com");
    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);
  }
} 

返回信息:

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

新版本4.5.3

需要认证

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.TrustSelfSignedStrategy;
import org.apache.http.ssl.SSLContexts;
public class HTTPSCertifiedClient extends HTTPSClient {
  public HTTPSCertifiedClient() { 

  } 

  @Override
  public void prepareCertificate() throws Exception {
    // 获得密匙库
    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 {
      // 密匙库的密码
      trustStore.load(instream, "password".toCharArray());
    } finally {
      instream.close();
    }
    SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, TrustSelfSignedStrategy.INSTANCE)
        .build();
    this.connectionSocketFactory = new SSLConnectionSocketFactory(sslcontext);
  }
}

跳过认证

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 {
    // 跳过证书验证
    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;
      }
    };
    // 设置成已信任的证书
    ctx.init(null, new TrustManager[] { tm }, null);
    this.connectionSocketFactory = new SSLConnectionSocketFactory(ctx);
  }
} 

总结

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; 

  /**
   * 初始化HTTPSClient
   *
   * @return 返回当前实例
   * @throws Exception
   */
  public CloseableHttpClient init() throws Exception {
    this.prepareCertificate();
    this.regist(); 

    return this.client;
  } 

  /**
   * 准备证书验证
   *
   * @throws Exception
   */
  public abstract void prepareCertificate() throws Exception; 

  /**
   * 注册协议和端口, 此方法也可以被子类重写
   */
  protected void regist() {
    // 设置协议http和https对应的处理socket链接工厂的对象
    Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
        .register("http", PlainConnectionSocketFactory.INSTANCE)
        .register("https", this.connectionSocketFactory)
        .build();
    PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
    HttpClients.custom().setConnectionManager(connManager); 

    // 创建自定义的httpclient对象
    this.client = HttpClients.custom().setConnectionManager(connManager).build();
    // CloseableHttpClient client = HttpClients.createDefault();
  }
}

工具类:

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) {
    // 设置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 {
    // 设置参数
    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);
      }
    }
  }
}

测试类:

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", "ankur.tandon.ap@xxx.com");
    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);
  } 

}

结果:

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

二、HttpURLConnection

三、Spring的RestTemplate

其它方式以后补充

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • 浅谈java调用Restful API接口的方式
(0)

相关推荐

  • 浅谈java调用Restful API接口的方式

    摘要:最近有一个需求,为客户提供一些RestfulAPI接口,QA使用postman进行测试,但是postman的测试接口与java调用的相似但并不相同,于是想自己写一个程序去测试RestfulAPI接口,由于使用的是HTTPS,所以还要考虑到对于HTTPS的处理.由于我也是首次使用Java调用restful接口,所以还要研究一番,自然也是查阅了一些资料. 分析:这个问题与模块之间的调用不同,比如我有两个模块frontend和backend,frontend提供前台展示,backend提供数据支

  • Java 调用Restful API接口的几种方式(HTTPS)

    摘要:最近有一个需求,为客户提供一些Restful API 接口,QA使用postman进行测试,但是postman的测试接口与java调用的相似但并不相同,于是想自己写一个程序去测试Restful API接口,由于使用的是HTTPS,所以还要考虑到对于HTTPS的处理.由于我也是首次使用Java调用restful接口,所以还要研究一番,自然也是查阅了一些资料. 分析:这个问题与模块之间的调用不同,比如我有两个模块front end 和back end,front end提供前台展示,back

  • Python调用REST API接口的几种方式汇总

    相信做过自动化运维的同学都用过REST API接口来完成某些动作.API是一套成熟系统所必需的接口,可以被其他系统或脚本来调用,这也是自动化运维的必修课. 本文主要介绍python中调用REST API的几种方式,下面是python中会用到的库. - urllib2 - httplib2 - pycurl - requests urllib2 - Sample1 import urllib2, urllib github_url = 'https://api.github.com/user/re

  • Java调用CXF WebService接口的两种方式实例

    通过http://localhost:7002/card/services/HelloWorld?wsdl访问到xml如下,说明接口写对了. 1.静态调用 // 创建WebService客户端代理工厂 JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); // 判断是否抛出异常 factory.getOutInterceptors().add(new LoggingInInterceptor()); // 注册webservic

  • SpringMVC Restful api接口实现的代码

    [前言] 面向资源的 Restful 风格的 api 接口本着简洁,资源,便于扩展,便于理解等等各项优势,在如今的系统服务中越来越受欢迎. .net平台有WebAPi项目是专门用来实现Restful api的,其良好的系统封装,简洁优雅的代码实现,深受.net平台开发人员所青睐,在后台服务api接口中,已经逐步取代了辉煌一时MVC Controller,更准确地说,合适的项目使用更加合适的工具,开发效率将会更加高效. python平台有tornado框架,也是原生支持了Restful api,在

  • java调用Restful接口的三种方法

    目录 1,基本介绍 2,HttpURLConnection实现 3.HttpClient实现 4.Spring的RestTemplate 1,基本介绍 Restful接口的调用,前端一般使用ajax调用,后端可以使用的方法比较多, 本次介绍三种: 1.HttpURLConnection实现 2.HttpClient实现 3.Spring的RestTemplate 2,HttpURLConnection实现 @Controller public class RestfulAction { @Aut

  • vue 调用 RESTful风格接口操作

    首先是简单的java接口代码 写了四个让前端请求的接口,以下为代码 @GetMapping("/v1/user/{username}/{password}") public Result login2(@PathVariable("username") String username, @PathVariable("password") String password){ return Result.succResult(200,username

  • Java调用第三方http接口的常用方式总结

    目录 1.概述 在Java项目中调用第三方接口的常用方式有 2.Java调用第三方http接口的方式 2.1 通过JDK网络类Java.net.HttpURLConnection 2.2 通过apache common封装好的HttpClient 2.3 通过Apache封装好的CloseableHttpClient 2.4 通过OkHttp 2.5 通过Spring的RestTemplate 2.6通过hutool的HttpUtil 3.总结 1.概述 在实际开发过程中,我们经常需要调用对方提

  • python调用接口的4种方式代码实例

    这篇文章主要介绍了python调用接口的4种方式代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python中调用API的几种方式: - urllib2 - httplib2 - pycurl - requests 1.urllib2 import urllib2, urllib github_url = 'https://api.github.com/user/repos' password_manager = urllib2.HTT

  • android monkey自动化测试改为java调用monkeyrunner Api

    众所周知,一般情况下我们使用android中的monkeyrunner进行自动化测试时,使用的是python语言来写测试脚本.不过,最近发现可以用java调用monkeyrunner Api,用java语言写测试脚本. 于是,就简单研究了一下.这里做一些总结.希望有对在研究的午饭可以有所用处. 开始时,搜素到一些零碎的教程,说使用java调用monkeyrunner时,需要导入android sdk  tools路径下的lib里面的4个包:ddmlib.jar,guavalib.jar,monk

随机推荐