欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-05-28 14:13:17
摘要:最近有一个需求,为客户提供一些restful api 接口,qa使用postman进行测试,但是postman的测试接口与java调用的相似但并不相同,于是想自己写一...

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

其它方式以后补充

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