`
hailong_qin
  • 浏览: 11443 次
  • 性别: Icon_minigender_1
  • 来自: 宁波
社区版块
存档分类
最新评论

HttpClient 实战

阅读更多
  最近,开发了一个RESTFul方式Web Service的跨应用调用。本人采用了Apache 的HttpClient客户端组件。
  HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。Commons-httpclient项目就是专门设计来简化HTTP客户端与服务器进行各种通讯编程。
  HttpClient工具类HttpClientUtil代码:
package com.credit56.ws.common;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.net.ssl.SSLHandshakeException;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.NoHttpResponseException;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
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.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;

/**
 * 
 * <p class="detail">
 * 功能:Http Client 工具类
 * </p>
 * 
 * @ClassName: HttpClientUtil
 * @version V1.0
 * @date 2014-1-27
 * @author qinhailong
 */
public class HttpClientUtil {

	private static int connectionTimeOut = 30000;

	private static int socketTimeOut = 60000;

	private static String DEFAULT_CHARSET = "utf-8";

	private static RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeOut)
			.setConnectTimeout(connectionTimeOut).build();

	// 自定义响应处理
	private static ResponseHandler<String> responseStringHandler = new ResponseHandler<String>() {
		public synchronized String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
			String responseBody = "";
			StatusLine statusLine = response.getStatusLine();
			int statusCode = statusLine.getStatusCode();
			if (statusCode >= 300) {
				throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
			}
			if (HttpStatus.SC_OK == statusCode) {
				HttpEntity entity = response.getEntity();
				if (null == entity) {
					throw new ClientProtocolException("Response contains no content");
				} else {
					responseBody = getResponseBody(entity);
				}
			}
			return responseBody;
		}
	};

	// 自定义响应处理
	private static ResponseHandler<HttpResponse> responseHandler = new ResponseHandler<HttpResponse>() {
		public synchronized HttpResponse handleResponse(HttpResponse response) throws ClientProtocolException,
				IOException {
			HttpEntity entity = response.getEntity();
			if (null == entity) {
				throw new ClientProtocolException("Response contains no content");
			} else {
				StringEntity stringEntity = new StringEntity(getResponseBody(entity), DEFAULT_CHARSET);
				response.setEntity(stringEntity);
			}
			return response;
		}
	};

	/**
	 * 
	 * <p class="detail">
	 * 功能:新建HttpClient
	 * </p>
	 * 
	 * @author qinhailong
	 * @date Jan 27, 2014
	 */
	public static HttpClient getNewHttpClient() {
		try {
			PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
			cm.setMaxTotal(100);
			HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
				public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
					if (executionCount >= 3) {
						// 如果超过最大重试次数,那么就不要继续了
						return false;
					}
					if (exception instanceof InterruptedIOException) {
						// Timeout
						return false;
					}
					if (exception instanceof ConnectTimeoutException) {
						// Connection refused
						return false;
					}
					if (exception instanceof NoHttpResponseException) {
						// 如果服务器丢掉了连接,那么就重试
						return true;
					}
					if (exception instanceof SSLHandshakeException) {
						// 不要重试SSL握手异常
						return false;
					}
					HttpClientContext clientContext = HttpClientContext.adapt(context);
					HttpRequest request = clientContext.getRequest();
					boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
					if (idempotent) {
						return true;
					}
					return false;
				}
			};
			CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
					.setRetryHandler(myRetryHandler).build();
			return httpClient;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 
	 * <p class="detail">
	 * 功能:Http GET 方法 返回类型为String
	 * </p>
	 * 
	 * @author qinhailong
	 * @date 2014-2-13
	 * @param url
	 *            请求URL
	 * @return String
	 * @throws HttpException
	 * @throws IOException
	 */
	public static String get(String url) throws HttpException, IOException {
		HttpClient httpClient = getNewHttpClient();
		HttpGet getMethod = getMethod(url);
		String responseBody = "";
		try {
			responseBody = httpClient.execute(getMethod, responseStringHandler);
		} finally {
			getMethod.releaseConnection();
		}
		return responseBody;
	}

	/**
	 * 
	 * <p class="detail">
	 * 功能:Http GET 方法 返回类型为HttpResponse
	 * </p>
	 * 
	 * @author qinhailong
	 * @date 2014-2-13
	 * @param url
	 *            请求URL
	 * @return HttpResponse
	 * @throws HttpException
	 * @throws IOException
	 */
	public static HttpResponse sendGetRequest(String url) throws HttpException, IOException {
		HttpClient httpClient = getNewHttpClient();
		HttpGet getMethod = getMethod(url);
		HttpResponse httpResponse = null;
		try {
			httpResponse = httpClient.execute(getMethod, responseHandler);
		} finally {
			getMethod.releaseConnection();
		}
		return httpResponse;
	}

	/**
	 * <p class="detail">
	 * 功能:POST请求 返回响应体 String 内容
	 * </p>
	 * 
	 * @author qinhailong
	 * @date 2014年1月27日
	 * @param url
	 *            请求地址
	 * @param postData
	 *            请求参数
	 * @return String
	 * @throws HttpException
	 */
	public static String post(String url, Map<String, String> postData) throws Exception {
		if (null == postData || postData.isEmpty()) {
			return get(url);
		}
		HttpPost postMethod = null;
		String responseBody = "";
		try {
			HttpClient httpClient = getNewHttpClient();
			postMethod = postMethod(url);
			Set<Entry<String, String>> entrySet = postData.entrySet();
			List<NameValuePair> formparams = new ArrayList<NameValuePair>();
			Iterator<Entry<String, String>> it = entrySet.iterator();
			while (it.hasNext()) {
				Map.Entry<String, String> entry = (Map.Entry<String, String>) it.next();
				formparams.add(new BasicNameValuePair(entry.getKey().toString(), entry.getValue().toString()));
			}
			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, DEFAULT_CHARSET);
			postMethod.setEntity(entity);
			responseBody = httpClient.execute(postMethod, responseStringHandler);
		} catch (Exception e) {
			throw e;
		} finally {
			postMethod.releaseConnection();
		}
		return responseBody;
	}

	/**
	 * 
	 * <p class="detail">
	 * 功能:POST请求 返回响应信息
	 * </p>
	 * 
	 * @author qinhailong
	 * @date 2014-2-13
	 * @param url
	 * @param postData
	 *            请求地址
	 * @return 请求参数
	 * @throws Exception
	 */
	public static HttpResponse sendPostRequest(String url, Map<String, String> postData) throws Exception {
		if (null == postData || postData.isEmpty()) {
			return sendGetRequest(url);
		}
		HttpPost postMethod = null;
		HttpResponse httpResponse = null;
		try {
			HttpClient httpClient = getNewHttpClient();
			postMethod = postMethod(url);
			Set<Entry<String, String>> entrySet = postData.entrySet();
			List<NameValuePair> formparams = new ArrayList<NameValuePair>();
			Iterator<Entry<String, String>> it = entrySet.iterator();
			while (it.hasNext()) {
				Map.Entry<String, String> entry = (Map.Entry<String, String>) it.next();
				formparams.add(new BasicNameValuePair(entry.getKey().toString(), entry.getValue().toString()));
			}
			if (null != formparams && formparams.size() > 0) {
				UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, DEFAULT_CHARSET);
				postMethod.setEntity(entity);
			}
			httpResponse = httpClient.execute(postMethod, responseHandler);
		} catch (Exception e) {
			throw e;
		} finally {
			postMethod.releaseConnection();
		}
		return httpResponse;
	}

	/**
	 * 
	 * <p class="detail">
	 * 功能:得到GET METHOD
	 * </p>
	 * 
	 * @author qinhailong
	 * @date 2014-2-12
	 * @param url
	 *            请求URL
	 * @return
	 */
	public static HttpGet getMethod(String url) {
		HttpGet getMethod = new HttpGet(url);
		getMethod.setConfig(requestConfig);
		getMethod.setHeaders(getHeaders());
		return getMethod;
	}

	/**
	 * 
	 * <p class="detail">
	 * 功能:得到POST METHOD
	 * </p>
	 * 
	 * @author qinhailong
	 * @date 2014-2-12
	 * @param url
	 *            请求URL
	 * @return
	 */
	public static HttpPost postMethod(String url) {
		HttpPost postMethod = new HttpPost(url);
		postMethod.setConfig(requestConfig);
		postMethod.setHeaders(getHeaders());
		return postMethod;
	}

	/**
	 * 
	 * <p class="detail">
	 * 功能:请求头信息
	 * </p>
	 * 
	 * @author qinhailong
	 * @date Jan 27, 2014
	 */
	private static Header[] getHeaders() {
		ArrayList<Header> headers = new ArrayList<Header>();
		headers.add(new BasicHeader("Accept", "text/html, text/json, text/xml, html/text, */*"));
		headers.add(new BasicHeader("Accept-Language", "zh-cn,en-us,zh-tw,en-gb,en;"));
		headers.add(new BasicHeader("Accept-Charset", "gbk,gb2312,utf-8,BIG5,ISO-8859-1;"));
		headers.add(new BasicHeader("Connection", "keep-alive"));
		headers.add(new BasicHeader("Cache-Control", "no-cache"));
		headers.add(new BasicHeader("Accept-Encoding", "gzip"));
		headers.add(new BasicHeader("User-Agent",
				"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; CIBA)"));
		return headers.toArray(new Header[0]);
	}

	/**
	 * 
	 * <p class="detail">
	 * 功能:从响应体内容
	 * </p>
	 * 
	 * @author qinhailong
	 * @date 2014-2-12
	 * @param httpResponse
	 *            httpClient 响应
	 * @return 响应体内容
	 * @throws IOException
	 * @throws IllegalStateException
	 */
	public static String getResponseBody(HttpEntity entity) throws IllegalStateException, IOException {
		StringBuffer respnseBody = new StringBuffer();
		BufferedReader in = null;
		try {
			InputStream is = entity.getContent();
			in = new BufferedReader(new InputStreamReader(is, DEFAULT_CHARSET));
			String line = null;
			while (null != (line = in.readLine())) {
				respnseBody.append(line);
			}
		} catch (IllegalStateException e1) {
			throw e1;
		} catch (IOException e2) {
			throw e2;
		} finally {
			in.close();
		}
		return respnseBody.toString();
	}

	/**
	 * 
	 * <p class="detail">
	 * 功能:从响应中得到响应体内容
	 * </p>
	 * 
	 * @author qinhailong
	 * @date 2014-2-12
	 * @param httpResponse
	 *            httpClient 响应
	 * @return 响应体内容
	 * @throws IOException
	 * @throws IllegalStateException
	 */
	public static String getResponseBody(HttpResponse httpResponse) throws IllegalStateException, IOException {
		String respnseBody = "";
		if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
			HttpEntity entity = httpResponse.getEntity();
			if (null != entity) {
				respnseBody = getResponseBody(entity);
			}
		}
		return respnseBody;
	}
}

由于响应体内容过大,是按块传送的,所以要用ResponseHandler回调的方式处理响应体内容,这样httpclient 会自己处理socket连接,不然的话,数据还没有读取完全,而socket又关闭了,会抛出socket关闭异常。
	// 自定义响应处理
	private static ResponseHandler<HttpResponse> responseHandler = new ResponseHandler<HttpResponse>() {
		public synchronized HttpResponse handleResponse(HttpResponse response) throws ClientProtocolException,
				IOException {
			HttpEntity entity = response.getEntity();
			if (null == entity) {
				throw new ClientProtocolException("Response contains no content");
			} else {
				StringEntity stringEntity = new StringEntity(getResponseBody(entity), DEFAULT_CHARSET);
				response.setEntity(stringEntity);
			}
			return response;
		}
	};


httpClient.execute(postMethod, responseHandler);
分享到:
评论

相关推荐

    全栈自动化测试实战 基于testng,httpclient,selenium.appium

    全栈自动化测试实战,是现代软件开发中一个关键的环节,尤其在追求高效、稳定和质量的项目中显得尤为重要。本书以testng、httpclient和selenium.appium为技术核心,详细介绍了如何进行端到端的自动化测试。下面将...

    HttpClient入门

    五、HttpClient实战示例 以下是一个简单的GET请求示例: ```java CloseableHttpClient httpClient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet("http://example.com"); CloseableHttpResponse ...

    HttpClient.入门和实战.docx

    HttpClient 入门和实战 HttpClient 是一个基于 HTTP/1.1 协议的客户端编程工具,可以用来发送 HTTP 请求和接收响应。HttpClient 可以用来实现 HTTP 客户端的各种功能,如发送 GET、POST、PUT、DELETE 等请求,上传...

    httpclient资料(自用)

    通过阅读《HttpClient实战》等技术书籍,以及参考官方文档和社区博客(如提供的博文链接),可以进一步了解HttpClient的高级特性和最佳实践。在实际开发中,HttpClient是一个强大且灵活的工具,能够帮助你轻松处理...

    HttpClient学习笔记

    五、HttpClient实战应用 在实际开发中,HttpClient常用于爬虫、API接口测试、数据同步等场景。例如,你可以用它来模拟用户登录、获取网页内容、提交表单数据等操作。 六、常见问题与解决方案 1. **连接关闭问题**:...

    httpclient发送get请求和post请求demo

    同时,通过阅读如"HttpClient发送get请求和post请求"这样的博客,你可以获取更多关于HttpClient实战中的技巧和最佳实践。在提供的压缩包文件中,`test-demo`和`httpclient-demo`可能包含了这些示例的源码,供你...

    HttpClient Https实战

    这篇博客“HttpClient Https实战”很可能详细介绍了如何使用HttpClient库来处理HTTPS连接,这是在互联网安全通信中不可或缺的一部分。 HttpClient库提供了丰富的API,使得开发者可以方便地发送GET、POST等各种HTTP...

    httpclient 所需jar以及使用实例

    项目中httpclient实战经典 里面包含了如何模拟客户端发送请求等经典代码

    angular5 httpclient的示例实战

    Angular 5 HTTPClient 实战示例 Angular 5 中的 HTTPClient 是一个功能强大且灵活的 HTTP 客户端,用于发送 HTTP 请求并处理响应。本文将通过一个示例实战,介绍 Angular 5 中的 HTTPClient 的使用方法和技术细节...

    httpclient httpclient.jar

    在本文中,我们将深入探讨HttpClient的核心概念、使用方法以及如何通过`httpclient.jar`进行实战应用。 首先,HttpClient的主要组件包括: 1. **HttpClient实例**:这是整个HTTP通信的核心,负责管理连接、请求和...

    httpclient4.3.5

    五、实战案例 通过以下代码示例,展示如何使用HttpClient 4.3.5发送一个简单的GET请求: ```java CloseableHttpClient httpClient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet(...

    httpclient4中文API和使用

    `httpClient笔记.docx`可能是用户或教程作者整理的关于使用HttpClient的笔记或实战案例,可能包括一些常见问题的解决方案,比如处理重定向、处理cookies、上传下载文件、使用HTTPS等。 学习HttpClient时,除了API...

    httpClient帮助文档

    9. **实战应用示例** - **简单的GET请求**:展示如何使用HttpGet发起一个简单的HTTP GET请求。 - **POST请求与表单提交**:演示如何使用HttpPost发送POST请求,包括表单数据的封装。 - **上传文件**:使用...

    httpclient-4.5所需jar包.zip

    三、实战示例 以下是一个简单的HttpClient 4.5使用示例,演示如何发送一个GET请求并获取响应: ```java import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; ...

    httpclient.zip

    五、实战示例 以下是一个简单的GET请求示例: ```java CloseableHttpClient httpClient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet("http://example.com"); CloseableHttpResponse response =...

    HttpClient4.2

    四、实战应用示例 在实际应用中,比如爬虫或者Web服务调用,HttpClient 4.2常被用来执行HTTP GET和POST请求,获取网页内容,发送表单数据等。例如,以下代码展示了如何使用HttpClient 4.2发送GET请求: ```java ...

    HttpClient实现POST GET和文件下载

    本篇文章将深入探讨如何利用HttpClient实现这些功能,并提供实战代码示例。 首先,让我们了解GET和POST两种HTTP请求方法的基本概念。GET是HTTP协议中最常见的请求方式,用于获取服务器上的资源,所有数据都包含在...

    httpclient4.0源文件

    五、实战应用 在实际开发中,我们可以利用HttpClient 4.0的灵活性来构建各种网络通信解决方案,例如: 1. **发送GET和POST请求**:通过构建`HttpGet`和`HttpPost`对象,设置URL和参数,然后使用HttpClient执行。 ...

    commons-httpclient-3.0-rc4.rar

    六、实战应用示例 在实际项目中,HttpClient常用于网页抓取、API调用、文件下载等场景。例如,通过PostMethod发送JSON数据到RESTful API,或使用GetMethod下载远程文件。 总结,Apache Commons HttpClient 3.0-rc4...

Global site tag (gtag.js) - Google Analytics