浅谈java调用Restful API接口的方式
|
摘要:最近有一个需求,为客户提供一些RestfulAPI接口,QA使用postman进行测试,但是postman的测试接口与java调用的相似但并不相同,于是想自己写一个程序去测试RestfulAPI接口,由于使用的是HTTPS,所以还要考虑到对于HTTPS的处理。由于我也是首次使用Java调用restful接口,所以还要研究一番,自然也是查阅了一些资料。 分析:这个问题与模块之间的调用不同,比如我有两个模块frontend和backend,frontend提供前台展示,backend提供数据支持。之前使用过Hession去把backend提供的服务注册成远程服务,在frontend端可以通过这种远程服务直接调到backend的接口。但这对于一个公司自己的一个项目耦合性比较高的情况下使用,没有问题。但是如果给客户注册这种远程服务,似乎不太好,耦合性太高。所以就考虑用一下方式进行处理。 基本介绍 Restful接口的调用,前端一般使用ajax调用,后端可以使用的方法比较多, 本次介绍三种: 1.HttpURLConnection实现 2.HttpClient实现 3.Spring的RestTemplate 一、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,String> paramBody) throws Exception {
return doPost(httpsClient,url,paramHeader,paramBody,DEFAULT_CHARSET);
}
public static String doPost(HTTPSClient httpsClient,String> paramBody,String charset) throws Exception {
String result = null;
HttpPost httpPost = new HttpPost(url);
setHeader(httpPost,paramHeader);
setBody(httpPost,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> paramBody) throws Exception {
return doGet(httpsClient,DEFAULT_CHARSET);
}
public static String doGet(HTTPSClient httpsClient,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,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,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,paramBody);
//String result = HTTPSClientUtil.doGet(httpsClient,null,null);
System.out.println(result);
}
}
(编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
