热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于HttpClient访问服务器以及上传文件

转载请注明出处,谢谢啦~项目背景:做项目经常用到http请求,市面上对于http请求的框架也是非常多,不乏一些经典如volley之流。但是我们有时候并不会用到那么大的框架,例如我们不会

转载请注明出处,谢谢啦~

项目背景:做项目经常用到http请求,市面上对于http请求的框架也是非常多,不乏一些经典如volley之流。但是我们有时候并不会用到那么大的框架,例如我们不会频繁的且大量的下载图片,不会有oom的顾虑,而且我们要做上传,而不是下载,再而且,我们不需要特别复杂的框架,只需要Android原生的就可以做到需求,那么我们为什么要导入那么大的框架。我们做上传的时候如果需要上传文件,市面上大多数框架又不支持了怎么办?!这个轻量级的封装就是针对这一需求而来。


首先这套工具是基于HttpClient的,我想没有人愿意去拼凑HttpURLConnection那烦躁的请求头,代码导入了httpmime的源码,并非jar包,对源码本着能不修改就不修改的原则,关于上传的进度显示采用了继承复写的方式来提供接口。下面进行简单的讲解。


public NetWork(String url){
		Log.d(TAG, "NetWork is started.");
		setHttpClient();
		post = new HttpPost(url);
	}

private void setHttpClient(){
		client = new DefaultHttpClient();
		client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, REQUEST_TIMEOUT);
		client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, SO_TIMEOUT);
		client.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, charSet);
	}

这是这个主类的初始化,我们可以看到这是对HttpClient进行了一些初始化操作,包括设置HttpClient 的超时时间,请求时间和编码集的设定。


/**
	 * If you want to add some headers in your http request,you must use this method before 
	 * {@link #doPost(Map, String, File, boolean, ProgressListener)}doPost.
	 * @param headersSet The Map you save your header's params.
	 */
	public void createCommonHeader(Map headersSet) {
		headers = new Header[headersSet.size()];
		Set> entrySet = headersSet.entrySet();
		int i = 0 ;
    	for (Entry entry : entrySet) {
    		headers[i] = new BasicHeader(entry.getKey(), entry.getValue());
    		i += 1;
		}
	}

这段代码是对请求头的一些设置,这里需要传递进来一个Map集合,集合里包括了所有的请求头,然后遍历封装到header集合里。

public String doPost(Map params,String fileType,File file,boolean hasHeader,ProgressListener listener){
		try {
			CustomMultiPartEntity multipartCOntent= new CustomMultiPartEntity(listener);
			
	        if(params!=null){
	        	Set> entrySet = params.entrySet();
	        	for (Entry entry : entrySet) {
	        		multipartContent.addPart(entry.getKey(), new StringBody(entry.getValue()));
				}
	        }
	        
	        if (fileType != null && file != null ) {
	        	// We use FileBody to transfer an file
	        	multipartContent.addPart(fileType, new FileBody(file));
			}
			
			post.setEntity(multipartContent);
			
			if (hasHeader) {
				if (headers != null) {
					post.setHeaders(headers);
				}
			}
			
			HttpResponse respOnse= client.execute(post);
			int statusCode = response.getStatusLine().getStatusCode();
			
			Log.v(TAG,  "statusCode : " + statusCode);
			//Using the same charset to read the response.
			String serverRespOnse= EntityUtils.toString(response.getEntity(),charSet);
			Log.v(TAG,  "serverResponse : " + serverResponse);
			
			if(statusCode!=200){
				Log.v(TAG,  "serverResponse : " + serverResponse);
	        	return null;
			}
			return serverResponse;
		} catch (Exception e) {
			Log.e(TAG, e.getMessage());
			return null;
		}
	}

这是最终的post请求,如果请求成功会返回服务器返回的数据,如果请求失败会返回null,调用时做下判断即可。


public class CustomMultiPartEntity extends MultipartEntity {

	private final ProgressListener listener;

	public CustomMultiPartEntity(final ProgressListener listener) {
		super();
		this.listener = listener;
	}

	public CustomMultiPartEntity(final HttpMultipartMode mode,
			final ProgressListener listener) {
		super(mode);
		this.listener = listener;
	}

	public CustomMultiPartEntity(HttpMultipartMode mode, final String boundary,
			final Charset charset, final ProgressListener listener) {
		super(mode, boundary, charset);
		this.listener = listener;
	}

	@Override
	public void writeTo(final OutputStream outstream) throws IOException {
		super.writeTo(new CountingOutputStream(outstream, this.listener));
	}

	public static interface ProgressListener {
		void transferred(long num);
	}

	public static class CountingOutputStream extends FilterOutputStream {

		private final ProgressListener listener;
		private long transferred;

		public CountingOutputStream(final OutputStream out,
				final ProgressListener listener) {
			super(out);
			this.listener = listener;
			this.transferred = 0;
		}

		public void write(byte[] b, int off, int len) throws IOException {
			out.write(b, off, len);
			this.transferred += len;
			this.listener.transferred(this.transferred);
		}

		public void write(int b) throws IOException {
			out.write(b);
			this.transferred++;
			this.listener.transferred(this.transferred);
		}
	}
}

这个类是对httpmime里的 MultipartEntity 类的复写 它提供了进度条的监听,如果需要此功能可以进行扩展。

同样如果不想导入httpmime源码,而是导入jar包的话,需要把这个类拿出来。作为自己的类进行扩展。

为了Android的开源精神,这份代码同样放到github上一份,欢迎fork和star。

library的下载地址:

github:基于HttpClientUtil的文件上传,提供进度条接口

csdn:基于HttpClient的文件上传,提供进度条接口


推荐阅读
  • 一键LNMP配置SSL证书实现全站HTTPS访问
    许多网站搭建者选择了便捷的一键LNMP安装包,但在网站部署完成后,配置SSL证书以支持HTTPS访问是一个不可或缺的步骤。本文将详细介绍如何通过简单的步骤完成这一过程。 ... [详细]
  • 本文探讨了在Qt框架下实现TCP多线程服务器端的方法,解决了一个常见的问题:服务器端仅能与最后一个连接的客户端通信。通过继承QThread类并利用socketDescriptor标识符,实现了多个客户端与服务器端的同时通信。 ... [详细]
  • 本文档提供了详细的MySQL安装步骤,包括解压安装文件、选择安装类型、配置MySQL服务以及设置管理员密码等关键环节,帮助用户顺利完成MySQL的安装。 ... [详细]
  • 深入探讨Web服务器与动态语言的交互机制:CGI、FastCGI与PHP-FPM
    本文详细解析了Web服务器(如Apache、Nginx等)与动态语言(如PHP)之间通过CGI、FastCGI及PHP-FPM进行交互的具体过程,旨在帮助开发者更好地理解这些技术背后的原理。 ... [详细]
  • 探讨了生成时间敏感的一次性伪随机密码的方法,旨在通过加入时间因素防止重放攻击。 ... [详细]
  • 深入解析轻量级数据库 SQL Server Express LocalDB
    本文详细介绍了 SQL Server Express LocalDB,这是一种轻量级的本地 T-SQL 数据库解决方案,特别适合开发环境使用。文章还探讨了 LocalDB 与其他轻量级数据库的对比,并提供了安装和连接 LocalDB 的步骤。 ... [详细]
  • 本文介绍了进程的基本概念及其在操作系统中的重要性,探讨了进程与程序的区别,以及如何通过多进程实现并发和并行。文章还详细讲解了Python中的multiprocessing模块,包括Process类的使用方法、进程间的同步与异步调用、阻塞与非阻塞操作,并通过实例演示了进程池的应用。 ... [详细]
  • 本文介绍了一个基本的同步Socket程序,演示了如何实现客户端与服务器之间的简单消息传递。此外,文章还概述了Socket的基本工作流程,并计划在未来探讨同步与异步Socket的区别。 ... [详细]
  • 深入解析Nacos服务自动注册机制
    本文将探讨Nacos服务自动注册的具体实现方法,特别是如何通过Spring事件机制完成服务注册。通过对Nacos源码的详细分析,帮助读者理解其背后的原理。 ... [详细]
  • 本文详细介绍了在PHP中如何获取和处理HTTP头部信息,包括通过cURL获取请求头信息、使用header函数发送响应头以及获取客户端HTTP头部的方法。同时,还探讨了PHP中$_SERVER变量的使用,以获取客户端和服务器的相关信息。 ... [详细]
  • 本文介绍如何通过Java代码调用阿里云短信服务API来实现短信验证码的发送功能,包括必要的依赖添加和关键代码示例。 ... [详细]
  • 在CentOS 7中部署Nginx并配置SSL证书
    本文详细介绍了如何在CentOS 7操作系统上安装Nginx服务器,并配置SSL证书以增强网站的安全性。适合初学者和中级用户参考。 ... [详细]
  • 本文探讨了在使用Apache Flink向Kafka发送数据过程中遇到的事务频繁失败问题,并提供了详细的解决方案,包括必要的配置调整和最佳实践。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置单节点的Redis服务,包括下载、解压、编译安装以及启动服务的具体步骤。 ... [详细]
  • 本文介绍了一个实用的工具类 `ListExtensions`,提供了多种针对 `List` 的扩展方法,包括无序和有序列表中的对象检索及计数功能。 ... [详细]
author-avatar
一号小蘑菇妖
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有