使用@PartMap 或任何等效于@FieldMap 的多部分发出多部分HTTP POST 请求
Making a Multipart HTTP POST request with @PartMap or any multipart equivalent to @FieldMap
我需要使用 form-data POST
上传文件和 JSON Object
个字符串,我的界面如下所示:
public interface uploadService {
@Multipart
@POST
Call<Void> uploadPhoto(@Part("photo") File file,
@PartMap Map<String, Object> params);
}
我遇到错误 End of Line 1 at Column 1
,我的 Callback
继续使用 OnError(...)
方法。简而言之,我的 HTTP 请求没有成功。我在想我哪里错了。
非常感谢您的回答。
PS: 请不要建议我使用 MultipartEntity extends HttpEntity
我已经读到它现在已被弃用。谢谢!
单独使用 PartMap 就足以处理多部分。
使用
@Multipart
@POST("api/registration")
Call<UserDetails> registerUser (@Header("Content-Length") long contentLength, @PartMap Map<String, RequestBody> params);
你可以创建一个 Requestody 来保存像
这样的文件
RequestBody.create(MediaType.parse("image/*"), file);
并将其添加到零件图中。
Map<String, RequestBody> params;
// 创建所有类型的 requestbody 并将其添加到此映射。
您可以通过
计算内容长度
long contentLength = 0;
Iterator iterator = params.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry pair = (Map.Entry)iterator.next();
try {
contentLength = contentLength + ((RequestBody)pair.getValue()).contentLength();
} catch (IOException e) {
e.printStackTrace();
}
}
。如果你想听文件上传的进度,那么你可以扩展 RequestBody 来提供有关进度的信息。
public class ProgressRequestBody extends RequestBody {
private File file;
private ProgressListener listener;
private int DEFAULT_BUFFER_SIZE = 4084;
@Override
public MediaType contentType() {
return MediaType.parse("image/*");
}
//The constructor
public ProgressRequestBody(final File file, final ProgressListener listener) {
this.file = file;
this.listener = listener;
}
//The method to overide
@Override
public void writeTo(BufferedSink sink) throws IOException {
long fileLength = file.length();
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
FileInputStream in = new FileInputStream(file);
long total = 0;
try {
int read;
while ((read = in.read(buffer)) != -1) {
this.listener.onProgress(total, fileLength);
total += read;
sink.write(buffer, 0, read);
}
} finally {
in.close();
}
}
//A simple callback
public interface ProgressListener {
void onProgress(final long current, final long max);
}
}
并用它来像
一样包装文件
public static RequestBody toImageRequestBody(File file, ProgressListener progressListener) {
ProgressRequestBody progressRequestBody = new ProgressRequestBody(file, progressListener);
return progressRequestBody;
}
保留它作为奖励 ;)
以下对我有用
界面
@Multipart
@POST("user/upload")
Call<JsonElement> upload(@PartMap Map<String, RequestBody> params);, user.getToken());
发送数据和图片如下
LinkedHashMap<String, RequestBody> mp= new LinkedHashMap<>();
RequestBody userId = RequestBody.create(
okhttp3.MediaType.parse("text/plain"), user.getUserId());
RequestBody userToken = RequestBody.create(
okhttp3.MediaType.parse("text/plain"), user.getToken());
//Instead of "text/plain" you can also send Json
mp.put("user_id", userId);
mp.put("token", userToken);
avatarFile = new File(uri.getPath());
RequestBody fileBody = RequestBody.create(MediaType.parse("image/gif"), avatarFile);
mp.put("files\"; filename=\"image.gif\"", fileBody);
我需要使用 form-data POST
上传文件和 JSON Object
个字符串,我的界面如下所示:
public interface uploadService {
@Multipart
@POST
Call<Void> uploadPhoto(@Part("photo") File file,
@PartMap Map<String, Object> params);
}
我遇到错误 End of Line 1 at Column 1
,我的 Callback
继续使用 OnError(...)
方法。简而言之,我的 HTTP 请求没有成功。我在想我哪里错了。
非常感谢您的回答。
PS: 请不要建议我使用 MultipartEntity extends HttpEntity
我已经读到它现在已被弃用。谢谢!
单独使用 PartMap 就足以处理多部分。 使用
@Multipart
@POST("api/registration")
Call<UserDetails> registerUser (@Header("Content-Length") long contentLength, @PartMap Map<String, RequestBody> params);
你可以创建一个 Requestody 来保存像
这样的文件RequestBody.create(MediaType.parse("image/*"), file);
并将其添加到零件图中。
Map<String, RequestBody> params;
// 创建所有类型的 requestbody 并将其添加到此映射。
您可以通过
long contentLength = 0;
Iterator iterator = params.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry pair = (Map.Entry)iterator.next();
try {
contentLength = contentLength + ((RequestBody)pair.getValue()).contentLength();
} catch (IOException e) {
e.printStackTrace();
}
}
。如果你想听文件上传的进度,那么你可以扩展 RequestBody 来提供有关进度的信息。
public class ProgressRequestBody extends RequestBody {
private File file;
private ProgressListener listener;
private int DEFAULT_BUFFER_SIZE = 4084;
@Override
public MediaType contentType() {
return MediaType.parse("image/*");
}
//The constructor
public ProgressRequestBody(final File file, final ProgressListener listener) {
this.file = file;
this.listener = listener;
}
//The method to overide
@Override
public void writeTo(BufferedSink sink) throws IOException {
long fileLength = file.length();
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
FileInputStream in = new FileInputStream(file);
long total = 0;
try {
int read;
while ((read = in.read(buffer)) != -1) {
this.listener.onProgress(total, fileLength);
total += read;
sink.write(buffer, 0, read);
}
} finally {
in.close();
}
}
//A simple callback
public interface ProgressListener {
void onProgress(final long current, final long max);
}
}
并用它来像
一样包装文件 public static RequestBody toImageRequestBody(File file, ProgressListener progressListener) {
ProgressRequestBody progressRequestBody = new ProgressRequestBody(file, progressListener);
return progressRequestBody;
}
保留它作为奖励 ;)
以下对我有用
界面
@Multipart
@POST("user/upload")
Call<JsonElement> upload(@PartMap Map<String, RequestBody> params);, user.getToken());
发送数据和图片如下
LinkedHashMap<String, RequestBody> mp= new LinkedHashMap<>();
RequestBody userId = RequestBody.create(
okhttp3.MediaType.parse("text/plain"), user.getUserId());
RequestBody userToken = RequestBody.create(
okhttp3.MediaType.parse("text/plain"), user.getToken());
//Instead of "text/plain" you can also send Json
mp.put("user_id", userId);
mp.put("token", userToken);
avatarFile = new File(uri.getPath());
RequestBody fileBody = RequestBody.create(MediaType.parse("image/gif"), avatarFile);
mp.put("files\"; filename=\"image.gif\"", fileBody);