使用@PartMap或与@FieldMap等效的任何多部分进行多部分HTTP POST请求

时间:2016-07-01 10:13:02

标签: android http-post httprequest okhttp retrofit2

我需要使用JSON Object使用form-data POST字符串上传文件,我的界面如下所示:

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我已经读过现在已弃用。谢谢!

2 个答案:

答案 0 :(得分:2)

以下是为我工作

<强>接口

@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);

答案 1 :(得分:1)

单独使用PartMap对于multipart来说就足够了。 使用

 @Multipart
    @POST("api/registration")
    Call<UserDetails> registerUser (@Header("Content-Length") long contentLength, @PartMap Map<String, RequestBody> params);

你可以创建一个Requestody来保存像

这样的文件
RequestBody.create(MediaType.parse("image/*"), file);

并将其添加到partmap。

Map<String, RequestBody> params; //创建所有类型的请求人并将其添加到此地图中。  您可以通过

计算内容长度
 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;
    }

保留奖金;)