HttpClient使用总结

在Android中,除了使用java.net包下的API访问HTTP服务之外,Android SDK附带了Apache的HttpClient API。Apache HttpClient是一个完善的HTTP客户端,它提供了对HTTP协议的全面支持,可以使用HTTP GET和POST进行访问。HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。


HttpGet
使用了HttpGet,请求参数直接附在URL后面,然后由HttpClient执行GET请求,如果响应成功的话,取得响应内如输入流,并转换成字符串

<span style="white-space:pre">		</span>HttpClient client = new DefaultHttpClient();
	<span style="white-space:pre">	</span>HttpGet get = new HttpGet(PATH + "/servlet/HttpRequest?id=1001&name=john&age=60");
<span style="white-space:pre">		</span>HttpResponse response = client.execute(get);
<span style="white-space:pre">		</span>if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
	<span style="white-space:pre">		</span>String result = EntityUtils.toString(response.getEntity());
	<span style="white-space:pre">	</span>}

HttpPost

使用了HttpPost,URL后面并没有附带参数信息,参数信息被包装成一个由NameValuePair类型组成的集合的形式,然后经过UrlEncodedFormEntity处理后调用HttpPost的setEntity方法进行参数设置,最后由HttpClient执行。

	<span style="white-space:pre">				</span>HttpClient client = new DefaultHttpClient();
					HttpPost post = new HttpPost(PATH+"/servlet/HttpRequest");
					List<NameValuePair> params = new ArrayList<NameValuePair>();
					params.add(new BasicNameValuePair("id", "1001"));
					params.add(new BasicNameValuePair("name", "john"));
					params.add(new BasicNameValuePair("age", "60"));
					HttpEntity formEntity = new UrlEncodedFormEntity(params);
					post.setEntity(formEntity);
					HttpResponse response = client.execute(post);
					if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
						InputStream is = response.getEntity().getContent();
						String result = inStream2String(is);
						System.out.println("result:" + result);
					}
HttpPost上传文件
GET请求和POST请求,参数都是文本数据类型,能满足普通的需求,不过在有的场合例如我们要用到上传文件的时候,就不能使用基本的GET请求和POST请求了,我们要使用多部件的POST请求。需要使用多部件POST操作上传一个文件到服务端。由于Android附带的HttpClient版本暂不支持多部件POST请求,所以我们需要用到一个HttpMime开源项目,该组件是专门处理与MIME类型有关的操作。因为HttpMime是包含在HttpComponents 项目中的,所以我们需要去apache官方网站下载HttpComponents,然后把其中的HttpMime.jar包放到项目中去。 服务端使用apache开源项目FileUpload进行处理,所以我们需要commons-fileupload和commons-io这两个项目的jar包。地址:http://commons.apache.org

客户端代码:
		HttpClient client = new DefaultHttpClient();
					// 视频路径 /mnt/sdcard/DCIM/100MEDIA/VIDEO0007.mp4
					HttpPost post = new HttpPost(PATH+"/servlet/HttpUpload");
					MultipartEntity multipartEntity = new MultipartEntity();
					FileBody filebodyVideo = new FileBody(new File("mnt/sdcard/DCIM/100MEDIA/VIDEO0007.mp4"));
					multipartEntity.addPart("file", filebodyVideo);
					multipartEntity.addPart("desc", new StringBody(
							"this is description."));
					post.setEntity(multipartEntity);
					HttpResponse response = client.execute(post);
					if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
						InputStream is = response.getEntity().getContent();
						String result = inStream2String(is);
					}

服务器端代码:
public class HttpUpload extends HttpServlet{
	
	@Override
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		boolean isMultipart = ServletFileUpload.isMultipartContent(request);
		if (isMultipart) {
			FileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload upload = new ServletFileUpload(factory);
			try {
				List<FileItem> list = upload.parseRequest(request);
				Iterator<FileItem> item = list.iterator();
				while (item.hasNext()) {
					FileItem fileItem = item.next();
					if (fileItem.isFormField()) {
						String paramName = fileItem.getName();
						String paramValue = fileItem.getString();
						System.out.println("paramName:" + paramName
								+ "-------paramValue:" + paramValue);
					} else {
						String fileName = fileItem.getName();
						byte[] data = fileItem.get();
						String filePath = getServletContext().getRealPath(
								"/files")
								+ "/" + fileName;
						FileOutputStream fos = new FileOutputStream(filePath);
						fos.write(data);
						fos.flush();
						fos.close();
						response.getWriter().write("SUCESS");
					}
				}
			} catch (FileUploadException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
单例HttpClient
在实际应用中,我们不能每次都新建HttpClient,而是应该只为整个应用创建一个HttpClient,并将其用于所有HTTP通信。此外,还应该注意在通过一个HttpClient同时发出多个请求时可能发生的多线程问题

1.扩展系统默认的Application,并应用在项目中。

2.使用HttpClient类库提供的ThreadSafeClientManager来创建和管理HttpClient。

重写了onCreate()方法,在系统启动时就创建一个HttpClient;重写了onLowMemory()和onTerminate()方法,在内存不足和应用结束时关闭连接,释放资源。需要注意的是,当实例化DefaultHttpClient时,传入一个由ThreadSafeClientConnManager创建的一个ClientConnectionManager实例,负责管理HttpClient的HTTP连接。

public class MyApplication extends Application{
	
	private HttpClient client;
	@Override
	public void onCreate() {
		super.onCreate();
		client = this.createHttpClient();
	}
	
	/**
	 * 获取HttpClient实例
	 * @return
	 */
	public HttpClient getHttpClient(){
		return client;
	}
	
	/**
	 * 创建HttpClient实例
	 * @return
	 */
	private HttpClient createHttpClient(){
		HttpParams params = new BasicHttpParams();
		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
		HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
		HttpProtocolParams.setUseExpectContinue(params, true);
		SchemeRegistry schReg = new SchemeRegistry();
		schReg.register(new Scheme("http",PlainSocketFactory.getSocketFactory(), 80));
		schReg.register(new Scheme("https",SSLSocketFactory.getSocketFactory(), 443));
		ClientConnectionManager conn = new ThreadSafeClientConnManager(params, schReg);
		HttpClient client = new DefaultHttpClient(conn, params);
		return client;
	}
	
	/**
	 * 关闭连接管理器并且释放资源
	 */
	private void shutDownHttpClient(){
		if(client != null && client.getConnectionManager() != null){
			client.getConnectionManager().shutdown();
		}
	}
	
	/**
	 * 在内存不足关闭连接
	 */
	@Override
	public void onLowMemory() {
		super.onLowMemory();
		shutDownHttpClient();
	}
	
	/**
	 * 应用结束时关闭连接
	 */
	@Override
	public void onTerminate() {
		super.onTerminate();
		shutDownHttpClient();
	}
}





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值