最近公司将原有的http协议接口,更改为了可支持https的双向接口,在查阅资料同时,将解决过程与大家分享。
使用的框架是Struts2,如有变动可自行修改相应代码。
首先,我们看看httpClient是个什么东西,它有什么作用,它能干嘛,它地基本用法?
基本使用详情①(转载):http://blog.csdn.net/wangpeng047/article/details/19624529
基本使用详情②(转载):http://blog.csdn.net/5iasp/article/details/8638800
--以上 基本可以让你对httpClient有个基本了解,也可以有个基本的使用。
httpClient是一个用于调用http协议的插件,要使用此插件需使用以下jar包:
commons-beanutils-1.8.0.jar
commons-codec.jar
commons-collections-3.2.jar
commons-lang-2.4.jar
commons-lang3-3.1.jar
commons-logging-1.1.1.jar
ezmorph-1.0.4.jar
httpclient-4.1.3.jar
httpclient-cache-4.1.3.jar
httpcore-4.1.4.jar
httpmime-4.1.3.jar
json-lib-2.4-jdk15.jar
以上jar下载地址:
http://download.csdn.net/detail/dcb_ripple/9477012
简单的的httpClient 使用,
1.httpClient 简单使用HttpPost调用http接口
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.http.HttpResponse;
- import org.apache.http.NameValuePair;
- import org.apache.http.auth.AuthScope;
- import org.apache.http.auth.UsernamePasswordCredentials;
- import org.apache.http.client.CredentialsProvider;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.entity.UrlEncodedFormEntity;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.entity.StringEntity;
- import org.apache.http.impl.client.BasicCredentialsProvider;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.message.BasicNameValuePair;
- import org.apache.http.util.EntityUtils;
- /**
- * 使用httpPost http登陆接口(无http摘要认证)
- */
- public static void testHttpClient(){
- //1.创建httpClient对象 (使用https协议,需要略过ssl验证,这里使用MySSLSocketFactory)
- HttpClient httpclient = new DefaultHttpClient();
- //url https地址
- String url ="http://192.168.10.215:8080/tnserver/property_manager/login";
- try {
- //2.创建列参数(httpPost使用)
- HttpPost httppost = new HttpPost(url);
- List<NameValuePair> list = new ArrayList<NameValuePair>();
- //将用户名与密码作为参数写入(username,password这两个参数是 根据你的接口协议而定)
- list.add(new BasicNameValuePair("username","admin"));
- list.add(new BasicNameValuePair("password","123456"));
- //3.写入请求头
- httppost.addHeader("Content-type", "application/x-www-form-urlencoded");
- //4.将参数写入到httpost中,并设置编码格式为UTF-8
- UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,"UTF-8");
- httppost.setEntity(entity);
- //5.执行
- HttpResponse post= httpclient.execute(httppost);
- //6.执行完毕,判断返回code码,200为正常
- if (post.getStatusLine().getStatusCode() == 200) {
- //7.获取返回json格式数据 注意,这里不能直接转java.lang.String进行强转,
- String conResult = EntityUtils.toString(post.getEntity());
- //8.处理返回数据....(完)
- JSONObject sobj = new JSONObject();
- sobj = JSONObject.fromObject(conResult);
- System.out.println(sobj);
- } else {
- System.out.println("失败....");
- }
- }catch(Exception e){
- e.printStackTrace();
- }
- }
</pre><p></p><pre>
以上这个例子很中规中矩,没有太多特殊处理的地方。那如果想象一下,要传入的参数是一个JSON格式的数据呢?
例如在登陆时将用户名与密码已json格式传入,
格式如下:
{
"username":"admin",
"password":"admin"
}
====那这个时候如果再采用List<NameValuePair> list = new ArrayList<NameValuePair>();list.add(new BasicNameValuePair("username","xxxx"));list.add(new BasicNameValuePair("password","xxxxx"));
的方式传参肯定是有问题的,因为它采用key/value的方式传值方式,与action中 ”getRequest().getParameter(“xxx”) “ 是一个道理
那么这个时候该怎么进行参数的传递呢?--看下面
2.httpClient 简单使用HttpPost 参数类型为JSON格式时
- /**
- * 使用httpPost 参数为JSON格式时(无http摘要认证)
- */
- public static void testHttpClient1(){
- HttpClient httpclient = new DefaultHttpClient();
- String url ="http://192.168.10.215:8080/tnserver/property_manager/login";
- try {
- HttpPost httppost = new HttpPost(url);
- httppost.addHeader("Content-type", "application/x-www-form-urlencoded");
- //此处略有不同的是,它是直接将JSON格式数据写如到httppost.setEntity实体中
- //并采用了StringEntity工具类,来进行转换。。。。
- JSONObject json = new JSONObject();
- json.put("username", "admin@qq.com");
- json.put("password", "123456");
- StringEntity entity = new StringEntity(json.toString(),"UTF-8");
- httppost.setEntity(entity);
- HttpResponse post= httpclient.execute(httppost);
- if (post.getStatusLine().getStatusCode() == 200) {
- String conResult = EntityUtils.toString(post.getEntity());
- JSONObject sobj = new JSONObject();
- sobj = JSONObject.fromObject(conResult);
- System.out.println(sobj);
- } else {
- System.out.println("失败....");
- }
- }catch(Exception e){
- e.printStackTrace();
- }finally{
- }
- }
是不是很简单,快试一试就知道了,上面的代码只需要Copy到自己的Main方法中就可以测试。。。。。
不过要注意测试之前请先弄清楚你的htpp接口根据接口进行相应更改
===========================================================
以上两个例子只可基于http协议,且服务器中没有设置身份认证的情况下。。。
服务器中有账户认证处理
具体如下:
- public static void testHttpClient2(){
- HttpClient httpclient = new DefaultHttpClient();
- String url ="http://xxxxx:xxxxx/tnserver/property_manager/login";
- try {
- HttpPost httppost = new HttpPost(url);
- //==========http认证过程===================== 如无需采用https协议进行调用,可忽略https认证过程
- //注:此方法只用于import org.apache.http.client.HttpClient; 新版本的认证
- //旧版本:import org.apache.commons.httpclient 认证方法如下:
- //Credentials defaultcreds = new UsernamePasswordCredentials("userxxx","pwdxxx");
- //httpClient.getState().setCredentials(AuthScope.ANY, defaultcreds);
- //注意。 旧版本的认证方式导入的包是 带 org.apache.commons.xxxx
- //创建https认证对象
- CredentialsProvider credsProvider = new BasicCredentialsProvider();
- //写入认证的用户名与密码
- UsernamePasswordCredentials creds = new UsernamePasswordCredentials("xxx", "xxx");
- //创建验证
- credsProvider.setCredentials(
- new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
- creds);
- //将认证写入到httpClient中
- ((DefaultHttpClient)httpclient).setCredentialsProvider(credsProvider);
- //=========Https认证===end=============================
- httppost.addHeader("Content-type", "application/x-www-form-urlencoded");
- JSONObject json = new JSONObject();
- json.put("username", "xxxx");
- json.put("password", "xxxxx");
- StringEntity entity = new StringEntity(json.toString());
- httppost.setEntity(entity);
- HttpResponse post= httpclient.execute(httppost);
- if (post.getStatusLine().getStatusCode() == 200) {
- String conResult = EntityUtils.toString(post.getEntity());
- JSONObject sobj = new JSONObject();
- sobj = JSONObject.fromObject(conResult);
- System.out.println(sobj);
- } else {
- System.out.println("失败....");
- }
- }catch(Exception e){
- e.printStackTrace();
- }finally{
- }
- }
这个认证账户密码是在http服务器中设置,所以别说不知账户密码是什么,直接问接口提供方。好,上面说了又一种旧版本的认证方式,这里直接附上 (注意这里的调用方式不一样,旧版本没有httpPost 而是PostMethod。。详情请百度。)
http://www.cnblogs.com/davidwang456/p/4062233.html
HTTPS如果略过证书认证过程
那又如果使用是基于HTTPS的呢?
HTTPS与HTTP有很大区别,它相比HTTP协议更安全,更高效。
HTTP与HTTP区别:http://blog.csdn.net/angussl/article/details/5557738
-正题:如何在调用时略过HTTPS 证书SSL认证过程
在调用https协议的的接口时都会遇到一个问题,那就是SSL证书怎么破,难道真的在本地安装?貌似有点不好弄,说实话我也不会.....
所以我们肯定是希望有这么一个东西,那就是可以在使用的时候忽略SSL认证的问题,那么这样我们就不必为SSL而苦恼。
代码:
- package com.httpclicent;
- import java.io.IOException;
- import java.net.Socket;
- import java.net.UnknownHostException;
- import java.security.KeyManagementException;
- import java.security.KeyStore;
- import java.security.KeyStoreException;
- import java.security.NoSuchAlgorithmException;
- import java.security.UnrecoverableKeyException;
- 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.HttpVersion;
- import org.apache.http.client.HttpClient;
- import org.apache.http.conn.ClientConnectionManager;
- import org.apache.http.conn.scheme.PlainSocketFactory;
- 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;
- import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
- import org.apache.http.params.BasicHttpParams;
- import org.apache.http.params.HttpParams;
- import org.apache.http.params.HttpProtocolParams;
- import org.apache.http.protocol.HTTP;
- /**
- * https SSL证书避免认证问题 (注意此处同样是新版本的SSL避免方式)
- * @author yzs
- *
- */
- public class MySSLSocketFactory extends SSLSocketFactory {
- SSLContext sslContext = SSLContext.getInstance("TLS");
- /**
- *
- * @param truststore
- * @throws NoSuchAlgorithmException
- * @throws KeyManagementException
- * @throws KeyStoreException
- * @throws UnrecoverableKeyException
- */
- public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
- super(truststore);
- TrustManager tm = new X509TrustManager() {
- public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- }
- public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- }
- public X509Certificate[] getAcceptedIssuers() {
- return null;
- }
- };
- sslContext.init(null, new TrustManager[] { tm }, null);
- }
- @Override
- public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
- return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
- }
- @Override
- public Socket createSocket() throws IOException {
- return sslContext.getSocketFactory().createSocket();
- }
- /**
- * 在使用时直接调用它即可,,,, 直接得略过https的ssl验证过程
- * @return
- */
- public static HttpClient getNewHttpClient() {
- try {
- KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
- trustStore.load(null, null);
- SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
- sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
- HttpParams params = new BasicHttpParams();
- HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
- HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
- SchemeRegistry registry = new SchemeRegistry();
- registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
- registry.register(new Scheme("https", sf, 443));
- ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
- return new DefaultHttpClient(ccm, params);
- } catch (Exception e) {
- return new DefaultHttpClient();
- }
- }
- }
有了这个Class一切都将不是问题,无需太大改动,只需要在创建HttpClicent时 使用 类中的getNewHttpClient即可
如下:
//1.创建httpClient对象 (使用https协议,需要略过ssl验证,这里使用MySSLSocketFactory)
HttpClient httpclient = MySSLSocketFactory.getNewHttpClient();
代码:
- public static void testHttpClient3(){
- //1.创建httpClient对象 (使用https协议,需要略过ssl验证,这里使用MySSLSocketFactory)
- HttpClient httpclient = MySSLSocketFactory.getNewHttpClient();
- <span style="white-space:pre"> </span>//http默认端口号是80 https为443
- String url ="http://xxxx:443/tnserver/property_manager/login";
- try {
- HttpPost httppost = new HttpPost(url);
- //==========https认证过程===================== 如无需采用https协议进行调用,客户了https认证过程
- //注:此方法只用于import org.apache.http.client.HttpClient; 新版本的认证
- //创建https认证对象
- CredentialsProvider credsProvider = new BasicCredentialsProvider();
- //写入认证的用户名与密码
- UsernamePasswordCredentials creds = new UsernamePasswordCredentials("xxx", "xxx");
- //创建验证
- credsProvider.setCredentials(
- new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
- creds);
- //将认证写入到httpClient中
- ((DefaultHttpClient)httpclient).setCredentialsProvider(credsProvider);
- //=========Https认证===end=============================
- httppost.addHeader("Content-type", "application/x-www-form-urlencoded");
- JSONObject json = new JSONObject();
- json.put("username", "xxx");
- json.put("password", "xxx");
- StringEntity entity = new StringEntity(json.toString());
- httppost.setEntity(entity);
- HttpResponse post= httpclient.execute(httppost);
- if (post.getStatusLine().getStatusCode() == 200) {
- String conResult = EntityUtils.toString(post.getEntity());
- JSONObject sobj = new JSONObject();
- sobj = JSONObject.fromObject(conResult);
- System.out.println(sobj);
- } else {
- System.out.println("失败....");
- }
- }catch(Exception e){
- e.printStackTrace();
- }finally{
- }
- }
ok,有以上代码基本可以实现大部分http与https接口的调用了。。。。
附上一个自己项目中实际使用的实例
需求:
代码实现Action:
- package cn.thinknet.action;
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.http.HttpResponse;
- import org.apache.http.NameValuePair;
- import org.apache.http.auth.AuthScope;
- import org.apache.http.auth.UsernamePasswordCredentials;
- import org.apache.http.client.CredentialsProvider;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.entity.UrlEncodedFormEntity;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.impl.client.BasicCredentialsProvider;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.message.BasicNameValuePair;
- import org.apache.http.util.EntityUtils;
- import net.sf.json.JSONArray;
- import net.sf.json.JSONObject;
- import cn.thinknet.bean.UserManage;
- import cn.thinknet.util.MySSLSocketFactory;
- public class UserManageAction extends BaseAction{
- private String msg;
- private List<UserManage> userManageList;
- private JSONArray resultJa;
- private String ids;
- private JSONObject result;
- private UserManage userManage;
- public String login(){
- //1.创建httpClient对象 (使用https协议,需要略过ssl验证,这里使用MySSLSocketFactory)
- //注:如无需使用https协议进行调用,则代码创建处理如下
- // HttpClient httpclient1 = new DefaultHttpClient();
- HttpClient httpclient = MySSLSocketFactory.getNewHttpClient();
- //url https地址
- String url ="https://192.168.10.216:443/tnserver/property_manager/login";
- try {
- //2.创建列参数(httpPost使用)
- List<NameValuePair> list = new ArrayList<NameValuePair>();
- //将用户名与密码作为参数写入(username,password这两个参数是 根据你的接口协议而定)
- list.add(new BasicNameValuePair("username","admin@163.com"));
- list.add(new BasicNameValuePair("password","123456"));
- //3.创建http对象
- HttpPost httppost = new HttpPost(url);
- //==========https认证过程===================== 如无需采用https协议进行调用,客户了https认证过程
- //注:此方法只用于import org.apache.http.client.HttpClient; 新版本的认证
- //旧版本:import org.apache.commons.httpclient 认证方法如下:
- //Credentials defaultcreds = new UsernamePasswordCredentials("userxxx","pwdxxx");
- //httpClient.getState().setCredentials(AuthScope.ANY, defaultcreds);
- //注意。 旧版本的认证方式导入的包是 带 org.apache.commons.xxxx
- //创建https认证对象
- CredentialsProvider credsProvider = new BasicCredentialsProvider();
- //写入认证的用户名与密码
- UsernamePasswordCredentials creds = new UsernamePasswordCredentials("admin", "123");
- //创建验证
- credsProvider.setCredentials(
- new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
- creds);
- //将认证写入到httpClient中
- ((DefaultHttpClient)httpclient).setCredentialsProvider(credsProvider);
- //============end=============================
- httppost.addHeader("Content-type", "application/x-www-form-urlencoded");
- //4.将参数写入到httpost中,并设置编码格式为UTF-8
- UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,"UTF-8");
- httppost.setEntity(entity);
- //5.执行
- HttpResponse post= httpclient.execute(httppost);
- //6.执行完毕,判断返回code码,200为正常
- if (post.getStatusLine().getStatusCode() == 200) {
- //7.获取返回json格式数据 注意,这里不能直接转java.lang.String进行强转,
- String conResult = EntityUtils.toString(post.getEntity());
- //8.处理返回数据....(完)
- JSONObject sobj = new JSONObject();
- sobj = JSONObject.fromObject(conResult);
- System.out.println(sobj);
- } else {
- System.out.println("失败....");
- }
- }catch(Exception e){
- e.printStackTrace();
- }finally{
- }
- return "success1";
- }
- public String getMsg() {
- return msg;
- }
- public void setMsg(String msg) {
- this.msg = msg;
- }
- public JSONArray getResultJa() {
- return resultJa;
- }
- public void setResultJa(JSONArray resultJa) {
- this.resultJa = resultJa;
- }
- public JSONObject getResult() {
- return result;
- }
- public void setResult(JSONObject result) {
- this.result = result;
- }
- public String getIds() {
- return ids;
- }
- public void setIds(String ids) {
- this.ids = ids;
- }
- public UserManage getUserManage() {
- return userManage;
- }
- public void setUserManage(UserManage userManage) {
- this.userManage = userManage;
- }
- public List<UserManage> getUserManageList() {
- return userManageList;
- }
- public void setUserManageList(List<UserManage> userManageList) {
- this.userManageList = userManageList;
- }
- }
======
完成!!! 没了,就这么多啦~~~
本人目前也是属于java两年新人,勿喷~~
最后附上简单Dome:
http://download.csdn.net/detail/dcb_ripple/9477041
联系客服