关于httpclient使用https提交参数

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

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




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值