内容简介: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接口生成和调用 图文详解
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Chinese Authoritarianism in the Information Age
Routledge / 2018-2-13 / GBP 115.00
This book examines information and public opinion control by the authoritarian state in response to popular access to information and upgraded political communication channels among the citizens in co......一起来看看 《Chinese Authoritarianism in the Information Age》 这本书的介绍吧!