1.通过OkhttpClient上传,首先添加OKHTTP的依赖
implementation 'com.squareup.okhttp3:okhttp:3.13.1'
//selImageList 图片或视频的地址路径
//此处图片和视频的命名规则为 VID_+时间+.mp4 ,IMG_+时间+.jpg
//此处图片和视频的路径如:/storage/emulated/0/DCIM/Camera/IMG_20200323_135044.jpg
private void uploadMp4OrJpg(ArrayList<ImageItem> selImageList) {
if(selImageList == null)
throw new IllegalStateException("selImageList is null");
OkHttpClient okHttpClient = OkHttpUtil.getInstance();
for (int i = 0; i < selImageList.size(); i++) {
String path = selImageList.get(i).path;
path = path.replace("/storage/emulated/0/DCIM/Camera/","");
File file = null;
MultipartBody.Builder builder = null;
if("VID_".equals(s.substring(0,4))){//当前要上传的是视频
file = new File("/storage/emulated/0/DCIM/Video/"+s); //根据路径创建file对象
builder = new MultipartBody.Builder()
.setType(MultipartBody.FORM) //按表单上传文件
.addFormDataPart(
"files",
file.getName(),
createCustomRequestBody(//自定义requestbody
MediaType.parse("application/octetstream"),
file,
new ProgressListener(){//文件上传进度监听
@Override
public void onProgress(
long totalBytes,
long remainingBytes,
boolean done
){
Logs.i(""+(int)((totalBytes - remainingBytes) * 100 / totalBytes));//当前上传的进度 1-100;
}
}
));
}else{//上传图片
file = new File(selImageList.get(i).path);
builder = new MultipartBody.Builder()
.setType(MultipartBody.FORM) //按表单上传文件
.addFormDataPart(
"files",
file.getName(),
RequestBody.create(//不对上传文件的进度进行监听
MediaType.parse("image/jpeg"),
file
)
);
}
//post 添加一些参数,后台通过request.getParameter("key1").toString() 取出
builder.addFormDataPart("key1",value1);
builder.addFormDataPart("key2",value2);
RequestBody requestBody = builder.build();
Request request = new Request.Builder()
.url("接口路径")
.header("Cookie", CacheUtil.Cookie)
.post(requestBody)
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Logs.i("上传"+"失败: " + e);
}
@Override
public void onResponse(Call call,
okhttp3.Response response) throws IOException {
Logs.i("上传"+"成功");
String json = response.body().string();
Logs.i("response.body()"+json);
}
});
}
}
2.自定义requestbody监听上传进度
public RequestBody createCustomRequestBody(
final MediaType contentType,
final File file,
final ProgressListener listener) {
return new RequestBody() {
@Override
public MediaType contentType() {
return contentType;
}
@Override
public long contentLength() {
return file.length();
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
Source source;
try {
source = Okio.source(file);
//sink.writeAll(source);
Buffer buf = new Buffer();
Long remaining = contentLength();
for (long readCount;
(readCount = source.read(buf, 2048)) != -1; ) {
sink.write(buf, readCount);
listener.onProgress(contentLength(), remaining -= readCount, remaining == 0);
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
}
3.进度监听接口
interface ProgressListener {
void onProgress(long totalBytes, long remainingBytes, boolean done);
}
4.okhttpclient封装的工具类
import java.util.concurrent.TimeUnit;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
public class OkHttpUtil {
private final static int READ_TIMEOUT = 100;
private final static int CONNECT_TIMEOUT = 60;
private final static int WRITE_TIMEOUT = 60;
private static volatile OkHttpClient okHttpClient;
private OkHttpUtil(){
okhttp3.OkHttpClient.Builder clientBuilder = new okhttp3.OkHttpClient.Builder();
//读取超时
clientBuilder.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS);
//连接超时
clientBuilder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS);
//写入超时
clientBuilder.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS);
//自定义连接池最大空闲连接数和等待时间大小,否则默认最大5个空闲连接
clientBuilder.connectionPool(new ConnectionPool(32,5,TimeUnit.MINUTES));
okHttpClient = clientBuilder.build();
}
public static OkHttpClient getInstance(){
if (null == okHttpClient){
synchronized (OkHttpUtil.class){
if (okHttpClient == null){
new OkHttpUtil();
return okHttpClient;
}
}
}
return okHttpClient;
}
}
5.后台接收
@RequestMapping(value = "/saveFiles",method = RequestMethod.POST)
@ResponseBody
public Map saveFile(HttpServletRequest request,HttpServletResponse response){
Map<String, Object> map = new HashMap<>();
List<MultipartFile> files = ((MultipartHttpServletRequest)request)
.getFiles("files");
MultipartFile file = null;
BufferedOutputStream stream = null;
for (int i = 0; i < files.size(); ++i) {
file = files.get(i);
if (!file.isEmpty()) {
try {
FileBean fileBean=new FileBean();
//取出post请求的参数
fileBean.setUserid(request.getParameter("key1").toString());
fileBean.setFfname(request.getParameter("key2").toString());
fileBean.setFfileid(UUID.randomUUID().toString());
//此处是将接收到的图片或视频存放到了数据库中,也可以保存到服务器的某个路径下
fileService.save(fileBean, file.getInputStream());
map.put("resultcode", "200");
} catch (Exception e) {
e.printStackTrace();
stream = null;
map.put("resultcode", "100");
}
} else {
map.put("resultcode", "100");
}
}
return map;
}