内容简介:Java调用Restful API接口的几种方式–HTTPS
最近有一个需求,为客户提供一些Restful API接口,QA使用postman进行测试,但是postman的测试接口与 java 调用的相似但并不相同,于是想自己写一个程序去测试Restful API接口,由于使用的是HTTPS,所以还要考虑到对于HTTPS的处理。由于我也是首次使用的Java调用REST风格的接口,所以还要研究一番,自然也是查阅了一些资料。
分析: 这个问题与模块之间的调用不同,比如我有两个模块前端和后端,前端提供前台展示,后端提供数据支持。之前使用过Hession去把后端提供的服务注册成远程服务,在前端可以通过这种远程服务直接调到后端的接口。但这对于一个公司自己的一个项目耦合性比较高的情况下使用,没有问题。但是如果给客户注册这种远程服务,似乎不太好,耦合性太高。所以就考虑用一下方式进行处理。
一,HttpClient的
HttpClient的大家也许比较熟悉但又比较陌生,熟悉是知道他可以远程调用比如请求一个URL,然后在响应里获取到返回状态和返回信息,但是今天讲的稍微复杂一点,因为今天的主题是HTTPS,这个牵涉到证书或用户认证的问题。
确定使用的HttpClient之后,查询相关资料,发现的HttpClient的新版本与老版本不同,随然兼容老版本,但已经不提倡老版本是使用方式,很多都已经标记为过时的方法或类。今天就分别使用老版本 4.2 和最新版本 4.5.3 来写代码。
老版本4.2
需要认证
在准备证书阶段选择的是使用证书认证
- 包 com.darren.test.https.v42;
- import java.io.File;
- import java.io.FileInputStream;
- import java.security.KeyStore;
- import org.apache.http.conn.ssl.SSLSocketFactory;
- 公共 类 HTTPSCertifiedClient 扩展 HTTPSClient {
- public HTTPSCertifiedClient(){
- }
- @覆盖
- 公共 无效 prepareCertificate() 抛出 异常{
- //获得密匙库
- KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
- FileInputStream instream = new FileInputStream(
- 新 文件( “C:/Users/zhda6001/Downloads/software/xxx.keystore” ));
- //密匙库的密码
- trustStore.load(instream, “password” .toCharArray());
- //注册密匙库
- this .socketFactory = new SSLSocketFactory(trustStore);
- //不校验域名
- socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
- }
跳过认证
在准备证书阶段选择的是跳过认证
- 包 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;
- 公共 类 HTTPSTrustClient 扩展 HTTPSClient {
- public HTTPSTrustClient(){
- }
- @覆盖
- 公共 无效 prepareCertificate() 抛出 异常{
- //跳过证书验证
- SSLContext ctx = SSLContext.getInstance( “TLS” );
- X509TrustManager tm = new X509TrustManager(){
- @覆盖
- 公共 无效 checkClientTrusted(X509Certificate []链,字符串authType) 抛出 CertificateException {
- }
- @覆盖
- 公共 无效 checkServerTrusted(X509Certificate []链,字符串authType) 抛出 CertificateException {
- }
- @覆盖
- public X509Certificate [] getAcceptedIssuers(){
- 返回 null ;
- }
- };
- //设置成已信任的证书
- ctx.init( null , new TrustManager [] {tm}, null );
- //穿件SSL socket工厂,并且设置不检查主机名称
- this .socketFactory = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
- }
总结
现在发现这两个类都继承了同一个类HTTPSClient,并且HTTPSClient继承了DefaultHttpClient类,可以发现,这里使用了模板方法模式。
- 包 com.darren.test.https.v42;
- 导入 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;
- 公共 抽象 类 HTTPSClient 扩展 DefaultHttpClient {
- 受保护的 SSLSocketFactory socketFactory;
- / **
- *初始化HTTPSClient
- *
- * @return返回当前实例
- * @例外
- * /
- 公共 HTTPSClient init() 抛出 异常{
- 这个 .prepareCertificate();
- 这个 .regist();
- 返回 这个 ;
- }
- / **
- *准备证书验证
- *
- * @例外
- * /
- public abstract void prepareCertificate() throws Exception;
- / **
- *注册协议和端口,此方法也可以被子类重写
- * /
- 保护 无效的 注册表(){
- ClientConnectionManager ccm = this .getConnectionManager();
- SchemeRegistry sr = ccm.getSchemeRegistry();
- sr.register( new Scheme( “https” , 443 ,socketFactory));
- }
下边是 工具 类
- 包 com.darren.test.https.v42;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- 导入 org.apache.http.HttpEntity;
- 导入 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;
- 公共 类 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 {
- 返回 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响应= httpsClient.execute(httpPost);
- if (response!= null ){
- HttpEntity resEntity = response.getEntity();
- if (resEntity!= null ){
- 结果= EntityUtils.toString(resEntity,字符集);
- }
- }
- 返回 结果;
- }
- public static String doGet(HTTPSClient httpsClient,String url,Map <String,String> paramHeader,
- Map <String,String> paramBody) throws Exception {
- 返回 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响应= httpsClient.execute(httpGet);
- if (response!= null ){
- HttpEntity resEntity = response.getEntity();
- if (resEntity!= null ){
- 结果= EntityUtils.toString(resEntity,字符集);
- }
- }
- 返回 结果;
- }
- private static void setHeader(HttpRequestBase request,Map <String,String> paramHeader){
- //设置标题
- if (paramHeader!= null ){
- 设置<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>();
- 设置<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(实体);
- }
- }
- }
然后是测试类:
- 包 com.darren.test.https.v42;
- import java.util.HashMap;
- import java.util.Map;
- 公共 类 HTTPSClientTest {
- 公共 静态 无效的 主要(字符串[]参数) 抛出 异常{
- 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);
- 的System.out.println(结果);
- }
- }
返回信息:
- <? xml version = “1.0” encoding = “utf-8” ?>
- < 令牌 > jkf8RL0sw + Skkflj8RbKI5hP1bEQK8PrCuTZPpBINqMYKRMxY1kWCjmCfT191Zpp88VV1aGHW8oYNWjEYS0axpLuGAX89ejCoWNbikCc1UvfyesXHLktcJqyUFiVjevhrEQxJPHncLQYWP + Xse5oD9X8vKFKk7InNTMRzQK7YBTZ / e3U7gswM / 5cvAHFl6o9rEq9cWPXavZNohyvnXsohSzDo + BXAtXxa1xpEDLy / 8小时/ UaP4n4dlZDJJ3B8t1Xh + CRRIoMOPxf7c5wKhHtOkEOeXW + xoPQKKSx5CKWwJpPuGIIFWF / PaqWg + JUOsVT7QGdPv8PMWJ9DwEwjTdxguDg == </ 令牌 >
新版本4.5.3
需要认证
- 包 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;
- 公共 类 HTTPSCertifiedClient 扩展 HTTPSClient {
- public HTTPSCertifiedClient(){
- }
- @覆盖
- 公共 无效 prepareCertificate() 抛出 异常{
- //获得密匙库
- KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
- FileInputStream instream = new FileInputStream(
- 新 文件( “C:/Users/zhda6001/Downloads/software/xxx.keystore” ));
- 尝试 {
- //密匙库的密码
- trustStore.load(instream, “password” .toCharArray());
- } 最后 {
- instream.close();
- }
- SSLContext sslcontext = SSLContexts.custom()。loadTrustMaterial(trustStore,TrustSelfSignedStrategy.INSTANCE)
- 。建立();
- this .connectionSocketFactory = new SSLConnectionSocketFactory(sslcontext);
- }
跳过认证
- 包 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;
- 公共 类 HTTPSTrustClient 扩展 HTTPSClient {
- public HTTPSTrustClient(){
- }
- @覆盖
- 公共 无效 prepareCertificate() 抛出 异常{
- //跳过证书验证
- SSLContext ctx = SSLContext.getInstance( “TLS” );
- X509TrustManager tm = new X509TrustManager(){
- @覆盖
- 公共 无效 checkClientTrusted(X509Certificate []链,字符串authType) 抛出 CertificateException {
- }
- @覆盖
- 公共 无效 checkServerTrusted(X509Certificate []链,字符串authType) 抛出 CertificateException {
- }
- @覆盖
- public X509Certificate [] getAcceptedIssuers(){
- 返回 null ;
- }
- };
- //设置成已信任的证书
- ctx.init( null , new TrustManager [] {tm}, null );
- this .connectionSocketFactory = new SSLConnectionSocketFactory(ctx);
- }
总结
- 包 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;
- 公共 抽象 类 HTTPSClient 扩展 HttpClientBuilder {
- 私有的 CloseableHttpClient客户端;
- 受保护的 ConnectionSocketFactory connectionSocketFactory;
- / **
- *初始化HTTPSClient
- *
- * @return返回当前实例
- * @例外
- * /
- public closeableHttpClient init() 抛出 Exception {
- 这个 .prepareCertificate();
- 这个 .regist();
- 返回 这个 .client;
- }
- / **
- *准备证书验证
- *
- * @例外
- * /
- public abstract void prepareCertificate() throws Exception;
- / **
- *注册协议和端口,此方法也可以被子类重写
- * /
- 保护 无效的 注册表(){
- //设置协议http和https对应的处理socket链接工厂的对象
- 注册表<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder。<ConnectionSocketFactory> create()
- .register( “http” ,PlainConnectionSocketFactory.INSTANCE)
- .register( “https” , this .connectionSocketFactory)
- 。建立();
- PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
- HttpClients.custom()setConnectionManager(连接管理)。
- //创建自定义的httpclient对象
- 这个 .client = HttpClients.custom()。setConnectionManager(connManager).build();
- // CloseableHttpClient client = HttpClients.createDefault();
- }
工具类:
- 包 com.darren.test.https.v45;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- 导入 org.apache.http.HttpEntity;
- 导入 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;
- 公共 类 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 {
- 返回 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响应= httpClient.execute(httpPost);
- if (response!= null ){
- HttpEntity resEntity = response.getEntity();
- if (resEntity!= null ){
- 结果= EntityUtils.toString(resEntity,字符集);
- }
- }
- 返回 结果;
- }
- public static String doGet(HttpClient httpClient,String url,Map <String,String> paramHeader,
- Map <String,String> paramBody) throws Exception {
- 返回 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响应= httpClient.execute(httpGet);
- if (response!= null ){
- HttpEntity resEntity = response.getEntity();
- if (resEntity!= null ){
- 结果= EntityUtils.toString(resEntity,字符集);
- }
- }
- 返回 结果;
- }
- private static void setHeader(HttpRequestBase request,Map <String,String> paramHeader){
- //设置标题
- if (paramHeader!= null ){
- 设置<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>();
- 设置<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(实体);
- }
- }
- }
测试类:
- 包 com.darren.test.https.v45;
- import java.util.HashMap;
- import java.util.Map;
- import org.apache.http.client.HttpClient;
- 公共 类 HTTPSClientTest {
- 公共 静态 无效的 主要(字符串[]参数) 抛出 异常{
- 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);
- 的System.out.println(结果);
- }
结果:
- <? xml version = “1.0” encoding = “utf-8” ?>
- < 令牌 > RxitF9 // 7NxwXJS2cjIjYhLtvzUNvMZxxEQtGN0u07sC9ysJeIbPqte3hCjULSkoXPEUYGUVeyI9jv7 / WikLrzxYKc3OSpaTSM0kCbCKphu0TB2Cn / nfzv9fMLueOWFBdyz + N0sEiI9K + 0Gp7920DFEncn17wUJVmC0u2jwvM5FAjQKmilwodXZ6a0Dq + D7dQDJwVcwxBvJ2ilhyIb3pr805Vppmi9atXrVAKO0ODa006wEJFOfcgyG5p70wpJ5rrBL85vfy9WCvkd1R7j6NVjhXgH2gNimHkjEJorMjdXW2gKiUsiWsELi / XPswao7 / CTWNwTnctGK8PX2ZUB0ZfA == </ 令牌 >
二,HttpURLConnection类
三,春节的RestTemplate
其它方式以后补充
原文地址 http://www.bieryun.com/562.html
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- RPC调用接口设计
- XRPC之接口双向调用
- C#动态调用WCF接口
- python调用接口数据写入hive
- 撮合平台 1.0.1 发布 暴露远程调用接口
- Java WebService接口生成和调用 图文详解
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。