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

来源:互联网 发布:手机淘宝怎么关注品牌 编辑:程序博客网 时间:2024/06/07 20:27

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

项目背景:做项目经常用到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;}@Overridepublic 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
原创粉丝点击