您的位置:首页 > 理论基础 > 计算机网络

关于httpclient使用https提交参数

2015-09-25 15:13 609 查看
首先,自己当时做这个任务的时候,借鉴了一位博主的文章,写这篇文章算是记录自己的工作历程吧,毕竟是个新人的开端。

http://www.blogjava.net/icewee/archive/2012/06/04/379947.html

http://www.blogjava.net/icewee/archive/2012/06/05/379983.html

首先是配置https访问的证书,tomcat和项目web.xml的配置文件,偷个懒,直接截图写好的excel表格





这样就配置好了单向和双向认证,可以启动web项目,直接通过浏览器进行认证了https://localhost:8443/走起

下面上httpclient的代码

先来一个测试的servlet

package com.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.security.cert.X509Certificate;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class GenXmlServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//输出对应的证书
X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
if (certs != null) {
int count = certs.length;
System.out.println("共检测到[" + count + "]个客户端证书");
for (int i = 0; i < count; i++) {
System.out.println("客户端证书 [" + (++i) + "]: ");
System.out.println("校验结果:" + verifyCertificate(certs[--i]));
System.out.println("证书详细:\r" + certs[i].toString());
}
} else {
if ("https".equalsIgnoreCase(request.getScheme())) {
System.out.println("这是一个HTTPS请求,但是没有可用的客户端证书");
} else {
System.out.println("这不是一个HTTPS请求,因此无法获得客户端证书列表 ");
}
}
String name=request.getParameter("name");
String method=request.getMethod();
System.out.println(method);
//get提交进行编码
if(method.equals("GET")){
name=new String(name.getBytes("ISO-8859-1"),"UTF-8");
}
System.out.println("---------------");
System.out.println(name+"我到了");
out.write(name+"我回来了");
out.flush();
out.close();
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

doGet(request, response);
}

private boolean verifyCertificate(X509Certificate certificate) {
boolean valid = true;
try {
certificate.checkValidity();
} catch (Exception e) {
e.printStackTrace();
valid = false;
}
return valid;
}

}


接下来就是单向和双向的get和post请求了,
单向get请求

package zhufei.danxiang;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.SSLContext;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

public class DXsg {

private static final String SERVER = "https://localhost:8443/WebTset/GenXmlServlet";

public final static void main(String[] args) throws Exception {
// Trust 服务端证书
SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(new File("e:\\https\\tomcat.keystore"), "password".toCharArray(),
new TrustSelfSignedStrategy())
.build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[] { "TLSv1" },
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
try {

//设置参数
String param="name="+URLEncoder.encode("张三", "UTF-8");
//System.out.println(param);
//建立get请求
HttpGet httpget = new HttpGet(SERVER+"?"+param);

System.out.println("executing request " + httpget.getRequestLine());
//提交请求并获取返回结果
CloseableHttpResponse response = httpclient.execute(httpget);
System.out.println("-----");
try {
//获得返回实体
HttpEntity entity = response.getEntity();

System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
//读取返回内容
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
String text;
while ((text = bufferedReader.readLine()) != null) {
System.out.println(text);
}
bufferedReader.close();
}
EntityUtils.consume(entity);

} finally {
response.close();
}
} finally {
httpclient.close();
}
}

}


单向post请求
package zhufei.danxiang;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.SSLContext;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

public class DXsp {

private static final String SERVER = "https://localhost:8443/WebTset/GenXmlServlet";

public final static void main(String[] args) throws Exception {
// Trust 服务端证书
SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(new File("e:\\https\\tomcat.keystore"), "password".toCharArray(),
new TrustSelfSignedStrategy())
.build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[] { "TLSv1" },
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
try {
//建立post请求
HttpPost httppost = new HttpPost(SERVER);
//请求参数
List<NameValuePair> formparams=new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("name", "张三"));
UrlEncodedFormEntity urlentity=new UrlEncodedFormEntity(formparams, Consts.UTF_8);
httppost.setEntity(urlentity);
System.out.println("executing request " + httppost.getRequestLine());
//提交请求并获取返回结果
CloseableHttpResponse response = httpclient.execute(httppost);
System.out.println("-----");
try {
//获得返回实体
HttpEntity entity = response.getEntity();

System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
//读取返回内容
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
String text;
while ((text = bufferedReader.readLine()) != null) {
System.out.println(text);
}
bufferedReader.close();
}
EntityUtils.consume(entity);

} finally {
response.close();
}
} finally {
httpclient.close();
}
}

}


双向认证get请求

package zhufei.shxiang;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.security.KeyStore;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

public class SXsg {

private static final String KEY_STORE_TYPE_JKS = "jks";
private static final String KEY_STORE_TYPE_P12 = "PKCS12";
private static final String SCHEME_HTTPS = "https";
private static final int HTTPS_PORT = 8443;
private static final String HTTPS_URL = "https://localhost:8443/WebTset/GenXmlServlet";
//客户端证书库
private static final String KEY_STORE_CLIENT_PATH = "E:/https/my.p12";
//客户端信任证书库(由服务端证书生成的证书库)
private static final String KEY_STORE_TRUST_PATH = "E:/https/my.truststore";
private static final String KEY_STORE_PASSWORD = "password";
private static final String KEY_STORE_TRUST_PASSWORD = "password";
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ssl();
}

private static void ssl() throws Exception {
//创建一个HttpClient对象
HttpClient httpClient = new DefaultHttpClient();
try {
//获取指定类型的keystore,储存密钥和证书
KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE_P12);
KeyStore trustStore = KeyStore.getInstance(KEY_STORE_TYPE_JKS);
//通过指定路径创建InputStream
InputStream ksIn = new FileInputStream(KEY_STORE_CLIENT_PATH);
InputStream tsIn = new FileInputStream(new File(KEY_STORE_TRUST_PATH));
try {
//从给定输出流中加载keysotre对象
keyStore.load(ksIn, KEY_STORE_PASSWORD.toCharArray());
trustStore.load(tsIn, KEY_STORE_TRUST_PASSWORD.toCharArray());
} finally {
//关闭流
try { ksIn.close(); } catch (Exception ignore) {}
try { tsIn.close(); } catch (Exception ignore) {}
}
//通过证书和密码,获取socketfactory套接字工厂
SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore, KEY_STORE_PASSWORD, trustStore);
//创建协Scheme对象,参数http/https(协议模式),默认端口,套接字工厂
Scheme sch = new Scheme(SCHEME_HTTPS, HTTPS_PORT, socketFactory);
//在连接管理器中注册中信息
httpClient.getConnectionManager().getSchemeRegistry().register(sch);
//设置参数
//????编码方式有问题
String param="name="+URLEncoder.encode("张三", "UTF-8");
//创建httppost请求
HttpGet httpget = new HttpGet(HTTPS_URL+"?"+param);

System.out.println("executing request" + httpget.getRequestLine());
//执行post请求,并且返回传递信息的HTTPResponse对象
HttpResponse response = httpClient.execute(httpget);
//获取响应实体
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine().getStatusCode());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
String text;
while ((text = bufferedReader.readLine()) != null) {
System.out.println(text);
}
bufferedReader.close();
}
EntityUtils.consume(entity);
} finally {
//使用连接管理器关闭httpclient
httpClient.getConnectionManager().shutdown();
}
}

}


双向认证post请求

package zhufei.shxiang;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import 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.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class SXsp {

private static final String KEY_STORE_TYPE_JKS = "jks";
private static final String KEY_STORE_TYPE_P12 = "PKCS12";
private static final String SCHEME_HTTPS = "https";
private static final int HTTPS_PORT = 8443;
private static final String HTTPS_URL = "https://localhost:8443/WebTset/GenXmlServlet";
//客户端证书库
private static final String KEY_STORE_CLIENT_PATH = "E:/https/my.p12";
//客户端信任证书库(由服务端证书生成的证书库)
private static final String KEY_STORE_TRUST_PATH = "E:/https/my.truststore";
private static final String KEY_STORE_PASSWORD = "password";
private static final String KEY_STORE_TRUST_PASSWORD = "password";
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ssl();
}

private static void ssl() throws Exception {
//创建一个HttpClient对象
HttpClient httpClient = new DefaultHttpClient();
try {
//获取指定类型的keystore,储存密钥和证书
KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE_P12);
KeyStore trustStore = KeyStore.getInstance(KEY_STORE_TYPE_JKS);
//通过指定路径创建InputStream
InputStream ksIn = new FileInputStream(KEY_STORE_CLIENT_PATH);
InputStream tsIn = new FileInputStream(new File(KEY_STORE_TRUST_PATH));
try {
//从给定输出流中加载keysotre对象
keyStore.load(ksIn, KEY_STORE_PASSWORD.toCharArray());
trustStore.load(tsIn, KEY_STORE_TRUST_PASSWORD.toCharArray());
} finally {
//关闭流
try { ksIn.close(); } catch (Exception ignore) {}
try { tsIn.close(); } catch (Exception ignore) {}
}
//通过证书和密码,获取socketfactory套接字工厂
SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore, KEY_STORE_PASSWORD, trustStore);
//创建协Scheme对象,参数http/https(协议模式),默认端口,套接字工厂
Scheme sch = new Scheme(SCHEME_HTTPS, HTTPS_PORT, socketFactory);
//在连接管理器中注册中信息
httpClient.getConnectionManager().getSchemeRegistry().register(sch);
//创建httppost请求
HttpPost httppost = new HttpPost(HTTPS_URL);
//构建post请求的表单参数
List<NameValuePair> formparams=new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("name", "张三"));
formparams.add(new BasicNameValuePair("xml", "<xml><name>烦烦烦</name></xml>"));
//设置编码方式
UrlEncodedFormEntity urlentity=new UrlEncodedFormEntity(formparams, Consts.UTF_8);
httppost.setEntity(urlentity);

System.out.println("executing request" + httppost.getRequestLine());
//执行post请求,并且返回传递信息的HTTPResponse对象
HttpResponse response = httpClient.execute(httppost);
//获取响应实体
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine().getStatusCode());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
String text;
while ((text = bufferedReader.readLine()) != null) {
System.out.println(text);
}
bufferedReader.close();
}
EntityUtils.consume(entity);
} finally {
//使用连接管理器关闭httpclient
httpClient.getConnectionManager().shutdown();
}
}

}


        做下总结吧,完成这个工作的时候对https的一些安全认证还不是了解的很清楚,只能说是勉强完成了交代的任务。然后呢,使用keytool生成证书的时候,在httpclient双向验证的时候,要多导出一个,在上面代码和excel表格中有说明,顺便导出服务器证书库的时候,注意姓氏的命名,本机测试localhost,实际应该是用访问域名,还没做到那一步,第一次自己弄的时候,很老实的写上了自己姓名的全拼,结果你懂的。然后配置tomcat和web.xml就没什么问题了,按部就班,不懂的直接百度。

对于httpclient,首先要去下载jar包,然后单向认证很简单,就那样,双向验证略复杂,还有就是post提交有自己的设置参数方法,以及编码方法,get提交我没有找到什么好办法,直接在url后面附加参数,怎么做你懂的,然后问题就来了,编码方法有问题,查了半天才解决,写参数的时候URLEncoder调用方法编码一次,在servlet中接受的时候判断提交方法,get提交就对获取的参数解码再编码一次,就OK了。

附带一些其他的参考博文
http://www.cnblogs.com/loveyakamoz/archive/2011/07/21/2112804.html http://blog.csdn.net/shimiso/article/details/7047447
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  https httpclient