这两天和新来的同事做一个项目,用到了文件上传,在这里记录下历程
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 android.app.AlertDialog
import android.app.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)
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)
// 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
我比较懒,没整理出一个基本类提供调用,直接写在业务里面了,这是不对的
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()
}
}