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

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

项目背景:做项目经常用到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<String,	String> headersSet) {
		headers = new Header[headersSet.size()];
		Set<Entry<String,String>> entrySet = headersSet.entrySet();
		int i = 0 ;
    	for (Entry<String, String> entry : entrySet) {
    		headers[i] = new BasicHeader(entry.getKey(), entry.getValue());
    		i += 1;
		}
	}

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

public String doPost(Map<String,String> params,String fileType,File file,boolean hasHeader,ProgressListener listener){
		try {
			CustomMultiPartEntity multipartContent = new CustomMultiPartEntity(listener);
			
	        if(params!=null){
	        	Set<Entry<String,String>> entrySet = params.entrySet();
	        	for (Entry<String, String> 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的文件上传,提供进度条接口

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值