HttpClient4.5详解

1.HttpClient简介


HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。现在HttpClient最新版本为 HttpClient 4.5 (GA)


2.HttpClient特性


1. 基于标准、纯净的java语言。

2. 以可扩展的面向对象的结构实现了Http全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE)。

3. 支持HTTPS协议。

4. 通过Http代理建立透明的连接。

5. 利用CONNECT方法通过Http代理建立隧道的https连接。

6. Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos认证方案。

7. 插件式的自定义认证方案。

8. 便携可靠的套接字工厂使它更容易的使用第三方解决方案。

9. 连接管理器支持多线程应用。支持设置最大连接数,同时支持设置每个主机的最大连接数,发现并关闭过期的连接。

10. 自动处理Set-Cookie中的Cookie。

11. 插件式的自定义Cookie策略。

12. Request的输出流可以避免流中内容直接缓冲到socket服务器。

13. Response的输入流可以有效的从socket服务器直接读取相应内容。

14. 在http1.0和http1.1中利用KeepAlive保持持久连接。

15. 直接获取服务器发送的response code和 headers。

16. 设置连接超时的能力。

17. 实验性的支持http1.1 response caching。

18. 源代码基于Apache License 可免费获取。


3.HttpClient使用方法


使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可。


1. 创建HttpClient对象。

2. 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。

3. 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。

4. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。

5. 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。

6. 释放连接。无论执行方法是否成功,都必须释放连接



4.HttpClient实例


4.1使用环境(maven配置)





4.2实例应用


4.2.1   利用post方法模拟用户登录请求


public void post(){
		
		//创建httppost
		HttpPost post = new HttpPost("http://localhost:8080/hotel/admin/checkLogin.action");
		
		//创建参数队列
		List<NameValuePair> list = new ArrayList<NameValuePair>();
		
		//存放post请求的参数
		list.add(new BasicNameValuePair("username", "admin"));
		list.add(new BasicNameValuePair("password", "123456"));	
		UrlEncodedFormEntity entity;
		
		try {
			entity = new UrlEncodedFormEntity(list,"UTF-8");
			// 将请求体内容加入请求中
			post.setEntity(entity);
			System.out.println(post.getURI());
			HttpResponse response = httpClient.execute(post);
			HttpEntity et = response.getEntity();
			if(et != null){
				System.out.println(EntityUtils.toString(et));
			}
		} catch (UnsupportedEncodingException e) {
			
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			
			e.printStackTrace();
		} catch (IOException e) {
			
			e.printStackTrace();
		}
		
	}

4.2.2   利用post方法模拟用户添加,提交表单


public void postData(){
		
		//创建post
		HttpPost post = new HttpPost("http://localhost:8080/hotel/reserve/addreserve.action");
		
		//创建参数队列
		List<NameValuePair> list = new ArrayList<NameValuePair>();
		
		//存放post请求的参数
		list.add(new BasicNameValuePair("typeId", "2"));
		list.add(new BasicNameValuePair("roomName", "STD007"));	
		list.add(new BasicNameValuePair("roomNumber", "207"));	
		list.add(new BasicNameValuePair("recordNumber", "H-16081808182400008"));	
		list.add(new BasicNameValuePair("arriveDate", "2016-08-25"));	
		list.add(new BasicNameValuePair("leaveDate", "2016-08-25"));	

		try {
			
			UrlEncodedFormEntity entity;
			
			entity=new UrlEncodedFormEntity(list,"utf-8");
						
			post.setEntity(entity);
			
			HttpResponse response = httpClient.execute(post);
			
			System.out.println(response.getEntity());
			
		} catch (IOException e) {
			
			e.printStackTrace();
		}
	}

4.2.3   利用get方法获取网页内数据


public void get(){
	        
        // 创建httpget.    
        HttpGet httpget = new HttpGet("http://localhost:8080/hotel/reserve/reserveList.action");  
        
        System.out.println("executing request " + httpget.getURI());  
        
        // 执行get请求.    
        HttpResponse response = null;
        
		try {
			response = httpClient.execute(httpget);
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}  
		try {
        	 // 获取响应实体    
			
            HttpEntity entity = response.getEntity();  
            System.out.println("--------------------------------------");  
            
            // 打印响应状态    
            System.out.println(response.getStatusLine());  
            System.out.println("--------------------------------------");
            
            if (entity != null) {  
               
                // 打印响应内容    
			System.out.println("Response content: " + EntityUtils.toString(entity,"utf-8"));
            }
		} catch (org.apache.http.ParseException e) {
			
			e.printStackTrace();
		} catch (IOException e) {
			
			e.printStackTrace();
		}               

	}

4.2.4    利用get方法获取网页内数据进行页面静态化


public boolean test(String url,String htmlPage){
		
		//创建默认的httpClient实例
		CloseableHttpClient httpClient=HttpClients.createDefault();
		
		// 创建httpget.    
		HttpGet get = new HttpGet(url);
		
		try {
			//执行get请求
			CloseableHttpResponse response = httpClient.execute(get);
			
			//获取响应实体    
			HttpEntity entity = response.getEntity();
						
			//定义BufferedReader输入流来读取URL的响应 
			BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent()));
			
			String pageContent="";
			
			//逐行读取数据
			while(true){
				String line = br.readLine();
				if(line == null){
					break;
				}else{
					pageContent+=line;
					pageContent+="\n";
				}
			}
			
			//创建字符输出流
			FileWriter writer = new FileWriter(htmlPage);
			
			PrintWriter fout = new PrintWriter(writer);
			
			fout.print(pageContent);
			fout.close();
		} catch (IOException e) {

		    System.out.println("IOException");
	            return false;
		}
		
		return true;
	}
	public static void main(String[] args) {
		Demo demo = new Demo();
		demo.test("http://localhost:8080/first/Power/test.action", "D:/a.html");
		System.out.println("已生成静态页面");
	}


5.HttpClient常见问题


5.1字符编码


某目标页的编码可能出现在两个地方,第一个地方是服务器返回的http头中,另外一个地方是得到的html/xml页面中。

对于像xml或者html这样的文件,允许作者在页面中直接指定编码类型。比如在html中会有<meta http-equiv="Content-Type" content="text/html; charset=gb2312"/>这样的标签;或者在xml中会有<?xml version="1.0" encoding="gb2312"?>这样的标签,在这些情况下,可能与http头中返回的编码信息冲突,需要用户自己判断到底那种编码类型应该是真正的编码。

5.2自动转向


根据RFC2616中对自动转向的定义,主要有两种:301和302。301表示永久的移走(Moved Permanently),当返回的是301,则表示请求的资源已经被移到一个固定的新地方,任何向该地址发起请求都会被转到新的地址上。302表示暂时的转向,比如在服务器端的servlet程序调用了sendRedirect方法,则在客户端就会得到一个302的代码,这时服务器返回的头信息中location的值就是sendRedirect转向的目标地址。


5.3处理HTTPS协议


HttpClient提供了对SSL的支持,在使用SSL之前必须安装JSSE。在Sun提供的1.4以后的版本中,JSSE已经集成到JDK中,如果你使用的是JDK1.4以前的版本则必须安装JSSE。JSSE不同的厂家有不同的实现。有两种方法可以打开https连接,第一种就是得到服务器颁发的证书,然后导入到本地的keystore中;另外一种办法就是通过扩展HttpClient的类来实现自动接受证书。


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值