Java 调用Restful API接口的几种方式(HTTPS)
摘要:最近有一个需求,为客户提供一些RestfulAPI接口,QA使用postman进行测试,但是postman的测试接口与java调用的相似但并不相同,于是想自己写一个程序去测试RestfulAPI接口,由于使用的是HTTPS,所以还要考虑到对于HTTPS的处理。由于我也是首次使用Java调用restful接口,所以还要研究一番,自然也是查阅了一些资料。
分析:这个问题与模块之间的调用不同,比如我有两个模块frontend和backend,frontend提供前台展示,backend提供数据支持。之前使用过Hession去把backend提供的服务注册成远程服务,在frontend端可以通过这种远程服务直接调到backend的接口。但这对于一个公司自己的一个项目耦合性比较高的情况下使用,没有问题。但是如果给客户注册这种远程服务,似乎不太好,耦合性太高。所以就考虑用一下方式进行处理。
一、HttpClient
HttpClient大家也许比较熟悉但又比较陌生,熟悉是知道他可以远程调用比如请求一个URL,然后在response里获取到返回状态和返回信息,但是今天讲的稍微复杂一点,因为今天的主题是HTTPS,这个牵涉到证书或用户认证的问题。
确定使用HttpClient之后,查询相关资料,发现HttpClient的新版本与老版本不同,随然兼容老版本,但已经不提倡老版本是使用方式,很多都已经标记为过时的方法或类。今天就分别使用老版本4.2和最新版本4.5.3来写代码。
老版本4.2
需要认证
在准备证书阶段选择的是使用证书认证
packagecom.darren.test.https.v42;
importjava.io.File;
importjava.io.FileInputStream;
importjava.security.KeyStore;
importorg.apache.http.conn.ssl.SSLSocketFactory;
publicclassHTTPSCertifiedClientextendsHTTPSClient{
publicHTTPSCertifiedClient(){
}
@Override
publicvoidprepareCertificate()throwsException{
//获得密匙库
KeyStoretrustStore=KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStreaminstream=newFileInputStream(
newFile("C:/Users/zhda6001/Downloads/software/xxx.keystore"));
//FileInputStreaminstream=newFileInputStream(newFile("C:/Users/zhda6001/Downloads/xxx.keystore"));
//密匙库的密码
trustStore.load(instream,"password".toCharArray());
//注册密匙库
this.socketFactory=newSSLSocketFactory(trustStore);
//不校验域名
socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
}
}
跳过认证
在准备证书阶段选择的是跳过认证
packagecom.darren.test.https.v42;
importjava.security.cert.CertificateException;
importjava.security.cert.X509Certificate;
importjavax.net.ssl.SSLContext;
importjavax.net.ssl.TrustManager;
importjavax.net.ssl.X509TrustManager;
importorg.apache.http.conn.ssl.SSLSocketFactory;
publicclassHTTPSTrustClientextendsHTTPSClient{
publicHTTPSTrustClient(){
}
@Override
publicvoidprepareCertificate()throwsException{
//跳过证书验证
SSLContextctx=SSLContext.getInstance("TLS");
X509TrustManagertm=newX509TrustManager(){
@Override
publicvoidcheckClientTrusted(X509Certificate[]chain,StringauthType)throwsCertificateException{
}
@Override
publicvoidcheckServerTrusted(X509Certificate[]chain,StringauthType)throwsCertificateException{
}
@Override
publicX509Certificate[]getAcceptedIssuers(){
returnnull;
}
};
//设置成已信任的证书
ctx.init(null,newTrustManager[]{tm},null);
//穿件SSLsocket工厂,并且设置不检查host名称
this.socketFactory=newSSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
}
}
总结
现在发现这两个类都继承了同一个类HTTPSClient,并且HTTPSClient继承了DefaultHttpClient类,可以发现,这里使用了模板方法模式。
packagecom.darren.test.https.v42;
importorg.apache.http.conn.ClientConnectionManager;
importorg.apache.http.conn.scheme.Scheme;
importorg.apache.http.conn.scheme.SchemeRegistry;
importorg.apache.http.conn.ssl.SSLSocketFactory;
importorg.apache.http.impl.client.DefaultHttpClient;
publicabstractclassHTTPSClientextendsDefaultHttpClient{
protectedSSLSocketFactorysocketFactory;
/**
*初始化HTTPSClient
*
*@return返回当前实例
*@throwsException
*/
publicHTTPSClientinit()throwsException{
this.prepareCertificate();
this.regist();
returnthis;
}
/**
*准备证书验证
*
*@throwsException
*/
publicabstractvoidprepareCertificate()throwsException;
/**
*注册协议和端口,此方法也可以被子类重写
*/
protectedvoidregist(){
ClientConnectionManagerccm=this.getConnectionManager();
SchemeRegistrysr=ccm.getSchemeRegistry();
sr.register(newScheme("https",443,socketFactory));
}
}
下边是工具类
packagecom.darren.test.https.v42;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.Map;
importjava.util.Set;
importorg.apache.http.HttpEntity;
importorg.apache.http.HttpResponse;
importorg.apache.http.NameValuePair;
importorg.apache.http.client.entity.UrlEncodedFormEntity;
importorg.apache.http.client.methods.HttpGet;
importorg.apache.http.client.methods.HttpPost;
importorg.apache.http.client.methods.HttpRequestBase;
importorg.apache.http.message.BasicNameValuePair;
importorg.apache.http.util.EntityUtils;
publicclassHTTPSClientUtil{
privatestaticfinalStringDEFAULT_CHARSET="UTF-8";
publicstaticStringdoPost(HTTPSClienthttpsClient,Stringurl,MapparamHeader,
MapparamBody)throwsException{
returndoPost(httpsClient,url,paramHeader,paramBody,DEFAULT_CHARSET);
}
publicstaticStringdoPost(HTTPSClienthttpsClient,Stringurl,MapparamHeader,
MapparamBody,Stringcharset)throwsException{
Stringresult=null;
HttpPosthttpPost=newHttpPost(url);
setHeader(httpPost,paramHeader);
setBody(httpPost,paramBody,charset);
HttpResponseresponse=httpsClient.execute(httpPost);
if(response!=null){
HttpEntityresEntity=response.getEntity();
if(resEntity!=null){
result=EntityUtils.toString(resEntity,charset);
}
}
returnresult;
}
publicstaticStringdoGet(HTTPSClienthttpsClient,Stringurl,MapparamHeader,
MapparamBody)throwsException{
returndoGet(httpsClient,url,paramHeader,paramBody,DEFAULT_CHARSET);
}
publicstaticStringdoGet(HTTPSClienthttpsClient,Stringurl,MapparamHeader,
MapparamBody,Stringcharset)throwsException{
Stringresult=null;
HttpGethttpGet=newHttpGet(url);
setHeader(httpGet,paramHeader);
HttpResponseresponse=httpsClient.execute(httpGet);
if(response!=null){
HttpEntityresEntity=response.getEntity();
if(resEntity!=null){
result=EntityUtils.toString(resEntity,charset);
}
}
returnresult;
}
privatestaticvoidsetHeader(HttpRequestBaserequest,MapparamHeader){
//设置Header
if(paramHeader!=null){
SetkeySet=paramHeader.keySet();
for(Stringkey:keySet){
request.addHeader(key,paramHeader.get(key));
}
}
}
privatestaticvoidsetBody(HttpPosthttpPost,MapparamBody,Stringcharset)throwsException{
//设置参数
if(paramBody!=null){
Listlist=newArrayList();
SetkeySet=paramBody.keySet();
for(Stringkey:keySet){
list.add(newBasicNameValuePair(key,paramBody.get(key)));
}
if(list.size()>0){
UrlEncodedFormEntityentity=newUrlEncodedFormEntity(list,charset);
httpPost.setEntity(entity);
}
}
}
}
然后是测试类:
packagecom.darren.test.https.v42;
importjava.util.HashMap;
importjava.util.Map;
publicclassHTTPSClientTest{
publicstaticvoidmain(String[]args)throwsException{
HTTPSClienthttpsClient=null;
httpsClient=newHTTPSTrustClient().init();
//httpsClient=newHTTPSCertifiedClient().init();
Stringurl="https://1.2.6.2:8011/xxx/api/getToken";
//Stringurl="https://1.2.6.2:8011/xxx/api/getHealth";
MapparamHeader=newHashMap<>();
//paramHeader.put("Content-Type","application/json");
paramHeader.put("Accept","application/xml");
MapparamBody=newHashMap<>();
paramBody.put("client_id","ankur.tandon.ap@xxx.com");
paramBody.put("client_secret","P@ssword_1");
Stringresult=HTTPSClientUtil.doPost(httpsClient,url,paramHeader,paramBody);
//Stringresult=HTTPSClientUtil.doGet(httpsClient,url,null,null);
System.out.println(result);
}
}
返回信息:
jkf8RL0sw+Skkflj8RbKI5hP1bEQK8PrCuTZPpBINqMYKRMxY1kWCjmCfT191Zpp88VV1aGHW8oYNWjEYS0axpLuGAX89ejCoWNbikCc1UvfyesXHLktcJqyUFiVjevhrEQxJPHncLQYWP+Xse5oD9X8vKFKk7InNTMRzQK7YBTZ/e3U7gswM/5cvAHFl6o9rEq9cWPXavZNohyvnXsohSzDo+BXAtXxa1xpEDLy/8h/UaP4n4dlZDJJ3B8t1Xh+CRRIoMOPxf7c5wKhHtOkEOeXW+xoPQKKSx5CKWwJpPuGIIFWF/PaqWg+JUOsVT7QGdPv8PMWJ9DwEwjTdxguDg==
新版本4.5.3
需要认证
packagecom.darren.test.https.v45;
importjava.io.File;
importjava.io.FileInputStream;
importjava.security.KeyStore;
importjavax.net.ssl.SSLContext;
importorg.apache.http.conn.ssl.SSLConnectionSocketFactory;
importorg.apache.http.conn.ssl.TrustSelfSignedStrategy;
importorg.apache.http.ssl.SSLContexts;
publicclassHTTPSCertifiedClientextendsHTTPSClient{
publicHTTPSCertifiedClient(){
}
@Override
publicvoidprepareCertificate()throwsException{
//获得密匙库
KeyStoretrustStore=KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStreaminstream=newFileInputStream(
newFile("C:/Users/zhda6001/Downloads/software/xxx.keystore"));
//FileInputStreaminstream=newFileInputStream(newFile("C:/Users/zhda6001/Downloads/xxx.keystore"));
try{
//密匙库的密码
trustStore.load(instream,"password".toCharArray());
}finally{
instream.close();
}
SSLContextsslcontext=SSLContexts.custom().loadTrustMaterial(trustStore,TrustSelfSignedStrategy.INSTANCE)
.build();
this.connectionSocketFactory=newSSLConnectionSocketFactory(sslcontext);
}
}
跳过认证
packagecom.darren.test.https.v45;
importjava.security.cert.CertificateException;
importjava.security.cert.X509Certificate;
importjavax.net.ssl.SSLContext;
importjavax.net.ssl.TrustManager;
importjavax.net.ssl.X509TrustManager;
importorg.apache.http.conn.ssl.SSLConnectionSocketFactory;
publicclassHTTPSTrustClientextendsHTTPSClient{
publicHTTPSTrustClient(){
}
@Override
publicvoidprepareCertificate()throwsException{
//跳过证书验证
SSLContextctx=SSLContext.getInstance("TLS");
X509TrustManagertm=newX509TrustManager(){
@Override
publicvoidcheckClientTrusted(X509Certificate[]chain,StringauthType)throwsCertificateException{
}
@Override
publicvoidcheckServerTrusted(X509Certificate[]chain,StringauthType)throwsCertificateException{
}
@Override
publicX509Certificate[]getAcceptedIssuers(){
returnnull;
}
};
//设置成已信任的证书
ctx.init(null,newTrustManager[]{tm},null);
this.connectionSocketFactory=newSSLConnectionSocketFactory(ctx);
}
}
总结
packagecom.darren.test.https.v45;
importorg.apache.http.config.Registry;
importorg.apache.http.config.RegistryBuilder;
importorg.apache.http.conn.socket.ConnectionSocketFactory;
importorg.apache.http.conn.socket.PlainConnectionSocketFactory;
importorg.apache.http.impl.client.CloseableHttpClient;
importorg.apache.http.impl.client.HttpClientBuilder;
importorg.apache.http.impl.client.HttpClients;
importorg.apache.http.impl.conn.PoolingHttpClientConnectionManager;
publicabstractclassHTTPSClientextendsHttpClientBuilder{
privateCloseableHttpClientclient;
protectedConnectionSocketFactoryconnectionSocketFactory;
/**
*初始化HTTPSClient
*
*@return返回当前实例
*@throwsException
*/
publicCloseableHttpClientinit()throwsException{
this.prepareCertificate();
this.regist();
returnthis.client;
}
/**
*准备证书验证
*
*@throwsException
*/
publicabstractvoidprepareCertificate()throwsException;
/**
*注册协议和端口,此方法也可以被子类重写
*/
protectedvoidregist(){
//设置协议http和https对应的处理socket链接工厂的对象
RegistrysocketFactoryRegistry=RegistryBuilder.create()
.register("http",PlainConnectionSocketFactory.INSTANCE)
.register("https",this.connectionSocketFactory)
.build();
PoolingHttpClientConnectionManagerconnManager=newPoolingHttpClientConnectionManager(socketFactoryRegistry);
HttpClients.custom().setConnectionManager(connManager);
//创建自定义的httpclient对象
this.client=HttpClients.custom().setConnectionManager(connManager).build();
//CloseableHttpClientclient=HttpClients.createDefault();
}
}
工具类:
packagecom.darren.test.https.v45;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.Map;
importjava.util.Set;
importorg.apache.http.HttpEntity;
importorg.apache.http.HttpResponse;
importorg.apache.http.NameValuePair;
importorg.apache.http.client.HttpClient;
importorg.apache.http.client.entity.UrlEncodedFormEntity;
importorg.apache.http.client.methods.HttpGet;
importorg.apache.http.client.methods.HttpPost;
importorg.apache.http.client.methods.HttpRequestBase;
importorg.apache.http.message.BasicNameValuePair;
importorg.apache.http.util.EntityUtils;
publicclassHTTPSClientUtil{
privatestaticfinalStringDEFAULT_CHARSET="UTF-8";
publicstaticStringdoPost(HttpClienthttpClient,Stringurl,MapparamHeader,
MapparamBody)throwsException{
returndoPost(httpClient,url,paramHeader,paramBody,DEFAULT_CHARSET);
}
publicstaticStringdoPost(HttpClienthttpClient,Stringurl,MapparamHeader,
MapparamBody,Stringcharset)throwsException{
Stringresult=null;
HttpPosthttpPost=newHttpPost(url);
setHeader(httpPost,paramHeader);
setBody(httpPost,paramBody,charset);
HttpResponseresponse=httpClient.execute(httpPost);
if(response!=null){
HttpEntityresEntity=response.getEntity();
if(resEntity!=null){
result=EntityUtils.toString(resEntity,charset);
}
}
returnresult;
}
publicstaticStringdoGet(HttpClienthttpClient,Stringurl,MapparamHeader,
MapparamBody)throwsException{
returndoGet(httpClient,url,paramHeader,paramBody,DEFAULT_CHARSET);
}
publicstaticStringdoGet(HttpClienthttpClient,Stringurl,MapparamHeader,
MapparamBody,Stringcharset)throwsException{
Stringresult=null;
HttpGethttpGet=newHttpGet(url);
setHeader(httpGet,paramHeader);
HttpResponseresponse=httpClient.execute(httpGet);
if(response!=null){
HttpEntityresEntity=response.getEntity();
if(resEntity!=null){
result=EntityUtils.toString(resEntity,charset);
}
}
returnresult;
}
privatestaticvoidsetHeader(HttpRequestBaserequest,MapparamHeader){
//设置Header
if(paramHeader!=null){
SetkeySet=paramHeader.keySet();
for(Stringkey:keySet){
request.addHeader(key,paramHeader.get(key));
}
}
}
privatestaticvoidsetBody(HttpPosthttpPost,MapparamBody,Stringcharset)throwsException{
//设置参数
if(paramBody!=null){
Listlist=newArrayList();
SetkeySet=paramBody.keySet();
for(Stringkey:keySet){
list.add(newBasicNameValuePair(key,paramBody.get(key)));
}
if(list.size()>0){
UrlEncodedFormEntityentity=newUrlEncodedFormEntity(list,charset);
httpPost.setEntity(entity);
}
}
}
}
测试类:
packagecom.darren.test.https.v45;
importjava.util.HashMap;
importjava.util.Map;
importorg.apache.http.client.HttpClient;
publicclassHTTPSClientTest{
publicstaticvoidmain(String[]args)throwsException{
HttpClienthttpClient=null;
//httpClient=newHTTPSTrustClient().init();
httpClient=newHTTPSCertifiedClient().init();
Stringurl="https://1.2.6.2:8011/xxx/api/getToken";
//Stringurl="https://1.2.6.2:8011/xxx/api/getHealth";
MapparamHeader=newHashMap<>();
paramHeader.put("Accept","application/xml");
MapparamBody=newHashMap<>();
paramBody.put("client_id","ankur.tandon.ap@xxx.com");
paramBody.put("client_secret","P@ssword_1");
Stringresult=HTTPSClientUtil.doPost(httpClient,url,paramHeader,paramBody);
//Stringresult=HTTPSClientUtil.doGet(httpsClient,url,null,null);
System.out.println(result);
}
}
结果:
RxitF9//7NxwXJS2cjIjYhLtvzUNvMZxxEQtGN0u07sC9ysJeIbPqte3hCjULSkoXPEUYGUVeyI9jv7/WikLrzxYKc3OSpaTSM0kCbCKphu0TB2Cn/nfzv9fMLueOWFBdyz+N0sEiI9K+0Gp7920DFEncn17wUJVmC0u2jwvM5FAjQKmilwodXZ6a0Dq+D7dQDJwVcwxBvJ2ilhyIb3pr805Vppmi9atXrVAKO0ODa006wEJFOfcgyG5p70wpJ5rrBL85vfy9WCvkd1R7j6NVjhXgH2gNimHkjEJorMjdXW2gKiUsiWsELi/XPswao7/CTWNwTnctGK8PX2ZUB0ZfA==
二、HttpURLConnection
三、Spring的RestTemplate
其它方式以后补充
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。