这两天和新来的同事做一个项目,用到了文件上传,在这里记录下历程
Android文件上传有各种各样的Http框架,我也就简单说说我常用的吧,LiteHttp,OkHttp的封装还没做完全,有时间会补上,这里先只列出LiteHttp的封装吧,有点乱七八糟的,大家凑合着看吧,jar我就不往上放了,传文件的时候就把文件做参数给进去就OK,这不是重点,往下看才是重点,把LiteHttp放在这里,只是想做个比较
package com.bohan.ems.mdm.utils.net;
import java.io.File;
import java.util.LinkedHashMap;
import com.alibaba.fastjson.JSONObject;
import com.bohan.ems.mdm.db.model.BaseResponseEntity;
import com.bohan.ems.mdm.utils.JsonUtils;
import com.bohan.ems.mdm.utils.log.SLog;
import com.litesuits.http.HttpConfig;
import com.litesuits.http.LiteHttp;
import com.litesuits.http.exception.HttpException;
import com.litesuits.http.impl.apache.entity.MultipartEntity;
import com.litesuits.http.listener.HttpListener;
import com.litesuits.http.log.HttpLog;
import com.litesuits.http.request.AbstractRequest;
import com.litesuits.http.request.BitmapRequest;
import com.litesuits.http.request.FileRequest;
import com.litesuits.http.request.StringRequest;
import com.litesuits.http.request.content.FileBody;
import com.litesuits.http.request.content.JsonBody;
import com.litesuits.http.request.param.HttpMethods;
import com.litesuits.http.response.Response;
import com.litesuits.http.utils.HttpUtil;
import .AlertDialog;
import .Application;
import android.content.Intent;
import android.graphics.Bitmap;
import android.text.TextUtils;
import android.widget.ImageView;
/**
* 异步请求
*/
public class AsyncHttpClient {
private LiteHttp httpClient;
private Application appContext;
public AsyncHttpClient(Application appContext) {
this.appContext = appContext;
this.initLiteHttp();
}
private void initLiteHttp() {
if (httpClient == null) {
HttpConfig config = new HttpConfig(appContext) // configuration
// quickly
.setDebugged(false) // log output when debugged
.setDetectNetwork(true) // detect network before connect
.setDoStatistics(true) // statistics of time and traffic
.setUserAgent("Mozilla/5.0 (...)") // set custom User-Agent
.setTimeOut(5000, 5000)// connect and socket timeout:
.setMaxMemCacheBytesSize(1 * 1000 * 1000)// 1M
.setSocketBufferSize(1 * 1000 * 1000);// 1M
;
httpClient = LiteHttp.newApacheHttpClient(config);
} else {
httpClient.getConfig() // configuration directly
.setDebugged(false) // log output when debugged
.setDetectNetwork(true) // detect network before connect
.setDoStatistics(true) // statistics of time and traffic
.setUserAgent("Mozilla/5.0 (...)") // set custom User-Agent
.setSocketBufferSize(1 * 1000 * 1000)// 1M
.setMaxMemCacheBytesSize(1 * 1000 * 1000)// 1M
.setTimeOut(5000, 5000); // connect and socket timeout:
// 10s
}
}
// 普通的get请求
public void get(String url, final HttpResponseListener responseListener) {
final StringRequest request = new StringRequest(url).setMethod(HttpMethods.Get);
request.setHttpListener(new HttpListener<String>() {
@Override
public void onSuccess(String res, Response<String> response) {
responseListener.onSuccess(response.getHttpStatus().getCode() + "", res);
}
@Override
public void onFailure(HttpException e, Response<String> response) {
responseListener.onFailure(e);
}
});
httpClient.executeAsync(request);
}
// 普通的post请求
public void post(String url, String jsonParam, final HttpResponseListener responseListener) {
// SLog.Console("请求url= " + url);
// SLog.Console("请求Token=" + MainApplication.getInstance().getToken());
// SLog.Console("请求DeviceId=" + MainApplication.getInstance().getDeviceId());
// SLog.Console("请求Request" + jsonParam);
final StringRequest request = new StringRequest(url).setMethod(HttpMethods.Post);
request.setHttpBody(new JsonBody(jsonParam));
request.setHttpListener(new HttpListener<String>() {
@Override
public void onSuccess(String res, Response<String> response) {
SLog.Console("返回response " + res);
BaseResponseEntity<JSONObject> bre = JsonUtils.json2Class(res, new BaseResponseEntity<JSONObject>().getClass());
// 成功不进行校验 只校验 2003 TOKEN失效情况
if ("2003".equals(bre.getCode())) {
// 发送关闭app广播
// Intent intent = new Intent();
// intent.setAction(ServiceConstant.INTENT_ACTION_CLOSEALL);
// appContext.sendBroadcast(intent);
}
responseListener.onSuccess(response.getHttpStatus().getCode() + "", res);
}
@Override
public void onFailure(HttpException e, Response<String> response) {
if (e != null && !TextUtils.isEmpty(e.getMessage()) && e.getMessage().contains("Network Is Not Avilable")) {
responseListener.onSuccess(HttpConstant.HTTP_SUCCESS, "{\"code\": -1, \"message\":\"连接服务器失败,请验证网络情况\"}");
} else {
responseListener.onFailure(e);
}
}
});
httpClient.executeAsync(request);
}
// 文件上传
public void postUpload(String url, File file, final HttpResponseListener responseListener) {
SLog.Console("请求url= " + url);
SLog.Console("请求Request" + file.getName());
final StringRequest request = new StringRequest(url).setMethod(HttpMethods.Post);
request.setHttpBody(new FileBody(file));
request.setHttpListener(new HttpListener<String>() {
@Override
public void onSuccess(String res, Response<String> response) {
SLog.Console("返回response " + res);
BaseResponseEntity<JSONObject> bre = JsonUtils.json2Class(res, new BaseResponseEntity<JSONObject>().getClass());
// 成功不进行校验 只校验 2003 TOKEN失效情况
// if ("2003".equals(bre.getCode())) {
// Intent intent = new Intent();
// intent.setAction(ServiceConstant.INTENT_ACTION_CLOSEALL);
// appContext.sendBroadcast(intent);
// appContext.stopService(new Intent(appContext, HeartbeatService.class));
// }
responseListener.onSuccess(response.getHttpStatus().getCode() + "", res);
}
@Override
public void onFailure(HttpException e, Response<String> response) {
if (e != null && !TextUtils.isEmpty(e.getMessage()) && e.getMessage().contains("Network Is Not Avilable")) {
responseListener.onSuccess(HttpConstant.HTTP_SUCCESS, "{\"code\": -1, \"message\":\"连接服务器失败,请验证网络情况\"}");
} else {
responseListener.onFailure(e);
}
}
});
httpClient.executeAsync(request);
}
}事情是这样的,我先用HttpUrlCOnnection,LiteHttp分别做了一个文件上传,因为这个东西比较老,指定没啥问题,我也就没多想,就把代码写完了,等着服务器老大哥叫我调试,结果老大哥说要用MultipartEntityBuilder,我就懵B了,这是个啥玩意,各种百度之后才知道这是个什么玩意,Http协议4.0以上版本出现的东西,这个东西服务端应用应该很多,Android这边一直都是有现成的开源框架,VOlly,StackHttp,LiteHttp,OKHttp等等吧,言归正传,还是说说文件上传吧
使用MultipartEntityBuilder 需要两个jar包,下载地址我放在下面了
HttpCore和HttpMIne下载地址http://download.csdn.net/detail/qq_15700209/9871024我比较懒,没整理出一个基本类提供调用,直接写在业务里面了,这是不对的
/**
* 上传日志文件
*
* @param pathFile
*/
public void uploadLogFile(String pathFile) {
HttpClient client = new DefaultHttpClient();
// "http://192.168.5.153:8080/appConsole/app/transDeviceLog.do"
HttpPost post = new HttpPost(logUrl);
File file = new File(pathFile);
try {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody("upfile", file, ContentType.DEFAULT_BINARY, file.getName());
builder.addTextBody("deviceNo", deviceNo, ContentType.DEFAULT_BINARY);
builder.addTextBody("token", token, ContentType.DEFAULT_BINARY);
// builder.addTextBody("deviceImei", deviceImei, ContentType.DEFAULT_BINARY);
HttpEntity entity = builder.build();
post.setEntity(entity);
} catch (Exception e) {
e.printStackTrace();
SLog.Console(e.toString());
} catch (Error error) {
error.printStackTrace();
}
try {
HttpResponse response = client.execute(post);
HttpEntity entityResponse = response.getEntity();
ContentType contentTypeResponse = ContentType.getOrDefault(entityResponse);
Charset newCharset = contentTypeResponse.getCharset();
String charset = "";
if (!StringUtils.isEmpty(newCharset.toString())) {
charset = newCharset.name();
}
// 获取请求返回的状态码
if (response.getStatusLine().getStatusCode() == 200) {
String content = StringUtil.inputStreamToString(entityResponse.getContent(), charset);
SLog.Console("上传日志文件返回json" + content);
BaseResponseEntity<Object> bre = JsonUtils.json2Class(content.replace("/n", ""), new BaseResponseEntity<Object>().getClass());
// JSONObject obj = JSON.parseObject(content);
if (HttpConstant.BUSINESS_SUCCESS.equals(bre.getCode())) {
Toast.makeText(mAppContext, "设备日志信息上传成功", Toast.LENGTH_SHORT).show();
} else {
SLog.Console("上传日志文件---错误信息" + bre.getMsg());
}
} else {
SLog.Console("传日志文件---网络连接失败");
}
ClearLogZipFile();
} catch (IOException e) {
e.printStackTrace();
} catch (Error error) {
error.printStackTrace();
}
}
















