文件上传原理
通过为表单元素设置Method=“post” enctype="multipart/form-data"属性,让表单提交的数据以二进制编码的方式提交,在接收此请求的Servlet中用二进制流来获取内容,就可以取得上传文件的内容,从而实现文件的上传。
enctype属性的选择值范围
- 1、application/x-www-form-urlencoded:
这是默认编码方式,它只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的值处理成url编码方式。 - 2、multipart/form-data:
这种编码方式的表单会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定的文件内容也封装到请求参数里。 -
3、text/plain:
这种方式主要适用于直接通过表单发送邮件的方式。
表单提交的片段
提交数据
@Part注解参数文件上传
使用Post请求,方法中定义@Part参数,该参数指定file控件的名称及上传后文件的名称
上传数据类型:multipart/form-data
@Part注解参数单文件上传
请求的方法定义如下
public interface NetService {
@Multipart
@POST("MyUploadServer/servlet/UpLoadFileServlet")
Call postUpLoadFile(@Part() MultipartBody.Part requestBody);
}
使用:锁定File,创建RequestBody,创建MultipartBody.Part
//指定上传文件
File file
= new File(Environment.getExternalStorageDirectory(), "3.jpg");
//封装请求体
//RequestBody body
//= RequestBody
//.create(MediaType.parse("multipart/form-data"), file);
//RequestBody body
//=RequestBody
//.create(MediaType.parse("application/otcet-stream"), file);
RequestBody body
= MultipartBody
.create(MultipartBody.FORM, file);
MultipartBody.Part part
= MultipartBody.Part
.createFormData("file", file.getName(), body);
//http://192.168.1.100/MyUploadServer/servlet/UpLoadFileServlet
String baseUrl = "http://169.254.38.24/";
new Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.build()
.create(NetService.class)
.postUpLoadFile(part)
.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
try {
showResult("onResponse" + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call call, Throwable t) {
showResult("onFailure" + t.getMessage());
}
});
@Part注解参数多文件上传带表单参数
使用Post请求,方法中定义多个@Part参数,向服务器中上传多个文件及其他表单域数据
接口方法定义
@Multipart
@POST("MyUploadServer/servlet/MyUploadServlet")
Call uploadFilesByPart(@Part() List parts);
代码使用
File file
= new File(Environment.getExternalStorageDirectory(), "1.txt");
File file1
= new File(Environment.getExternalStorageDirectory(), "2.png");
List parts
= new ArrayList<>();
RequestBody body
= MultipartBody.create(MultipartBody.FORM, file);
RequestBody body1
= MultipartBody.create(MultipartBody.FORM, file1);
MultipartBody.Part part
= MultipartBody.Part.createFormData("file", file.getName(), body);
MultipartBody.Part part1
= MultipartBody.Part.createFormData("file", file1.getName(), body1);
MultipartBody.Part part2
= MultipartBody.Part.createFormData("username", "zxn001");
parts.add(part);
parts.add(part1);
parts.add(part2);
String baseUrl = "http://169.254.38.24/";
new Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.build()
.create(NetService.class)
.uploadFilesByPart(parts)
.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
try {
showResult("onResponse" + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call call, Throwable t) {
showResult("onFailure" + t.getMessage());
}
});
@PartMap注解参数多文件上传带表单参数
Post请求,方法中定义@PartMap参数,向服务器中上传多个文件及其他表单域数据
使用此种方式变量的书写格式:
ile"; filename="123.jpg
(表单控件名称";filename="保存在服务其端的文件名称)
web端:
Content-Disposition: form-data; name="file"; filename="1.txt"
接口方法定义
@Multipart
@POST("MyUploadServer/servlet/MyUploadServlet")
Call uploadFilesByPartMap(@PartMap() Map map);
代码使用
final File file
= new File(Environment.getExternalStorageDirectory(), "1.txt");
final File file1
= new File(Environment.getExternalStorageDirectory(), "2.png");
final RequestBody body
= MultipartBody.create(MultipartBody.FORM, file);
final RequestBody body1
= MultipartBody.create(MultipartBody.FORM, file1);
final RequestBody body2 =RequestBody.create(MultipartBody.FORM, "zxn001");
//body =MultipartBody.Part.createFormData("file", //file.getName(), body).body();
//body1 =MultipartBody.Part.createFormData("file", //file.getName(), body1).body();
//final RequestBody body2 = //MultipartBody.Part.createFormData("username", //"zxn001").body();
String baseUrl = "http://169.254.38.24/";
new Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.build()
.create(NetService.class)
.uploadFilesByPartMap(new HashMap(){
{
put("file\"; filename=\""+file.getName(), body);
put("file\"; filename=\""+file1.getName(), body1);
put("username",body2);
}
})
.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
try {
showResult("onResponse"+response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call call, Throwable t) {
showResult("onFailure"+t.getMessage());
}
});
@Body注解参数多文件上传带表单参数
使用Post请求,方法中定义@Body参数,向服务器中上传多个文件及其他表单域数据
接口方法定义如下
@POST("MyUploadServer/servlet/MyUploadServlet")
Call uploadFilesByody(@Body MultipartBody multipartBody);
代码使用
File file
= new File(Environment.getExternalStorageDirectory(), "a.jpg");
File file1
= new File(Environment.getExternalStorageDirectory(), "d.jpg");
MultipartBody.Builder builder
= new MultipartBody.Builder();
RequestBody body
= MultipartBody
.create(MultipartBody.FORM, file);
RequestBody body1
= MultipartBody.create(MultipartBody.FORM, file1);
MultipartBody multipartBody
= builder
.addFormDataPart("file", file.getName(), body)
.addFormDataPart("file", file1.getName(), body1)
.addFormDataPart("username", "zxn123")
.setType(MultipartBody.FORM)
.build();
String baseUrl = "http://169.254.38.24/";
new Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.build()
.create(NetService.class)
.uploadFilesByody(multipartBody)
.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
try {
showResult("onResponse" + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call call, Throwable t) {
showResult("onFailure" + t.getMessage());
}
});
上传的数据传输细节