当前位置: 移动技术网 > IT编程>开发语言>Java > Java 调用Restful API接口的几种方式(HTTPS)

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

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

其它方式以后补充

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网