Android & Retrofit2 - 在多部分请求中发布图像文件
Android & Retrofit2 - posting image file in multipart request
我正在制作一个应用程序,我必须在其中将图片从图库发送到服务器。
这些应该是 headers(根据养蜂场)。
Content-Type:image/jpeg
X-Filename:photo.jpg
但在拦截器的日志中,只有 X-Filename,尽管我尝试了多种方法,但我 运行 没有想法。
服务器响应 200 但下一次调用(提交图像)returns 500 在 post 结束时出错。
这些是方法:
@Multipart
@POST("uploads")
Observable<String> uploadImage(
@Header("Content-Type") String contentType,
@Header("X-Filename") String fileName,
@Header("Authorization") String token,
@Part MultipartBody.Part file
);
@GET("uploads/{fileId}/commit")
Observable<String> commitFile(
@Header("Content-Type") String type,
@Header("Authorization") String token,
@Path("fileId") String fileId
);
OkHttp 客户端:
private OkHttpClient createApiClient(Context context) {
int cacheSize = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(context.getCacheDir(), cacheSize);
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(chain -> {
Request request = chain.request().newBuilder().build();
request.newBuilder().addHeader("Content-Type", "application/json");
Timber.d("Request: [%s] %s", request.method(), request.url());
Timber.d("Request: %s", request.headers().toString());
if (request.body() != null) {
Timber.d("Request: %s", request.body().toString());
}
return chain.proceed(request);
});
builder.cache(cache);
return builder.build();
}
生成的日志:
D/NetModule: Request: [POST] https://winged-guild-133523.appspot.com/api/v1/uploads
D/NetModule: Request: X-Filename: asura.png
Authorization: HAYVi3clcqjug53IPS6AYMgzCPGnDE3Si
D/NetModule: Request: retrofit2.RequestBuilder$ContentTypeOverridingRequestBody@7c37f46
Postman 也会发生同样的事情 - Postman screenshot
提交失败并出现此错误:(抱歉格式丑陋)
{
"errorCode": "ImagesServiceFailureException",
"errorParam": "",
"errorMessage":"com.google.appengine.api.images.ImagesServiceFailureException: "
}
正如我所说,我 运行 没有想法,非常感谢任何有关此上传问题的帮助。
(edit) PS: 通过省略 @Header("Content-Type") String contentType在app中,在Postman中使用application/x-www-form-urlencoded,图片上传和提交都成功,但返回的图片url没有元数据,因此无法显示.
这是我使用改造的代码
@Multipart
@POST(ServiceConfig.API_CREATE_DEPENDENT_ACCOUNT)
@Headers({
"Accept: application/json",
"Accept-Encoding: gzip"
})
Call<DataResponse<CreateDependentAccountResponse>> createDependentAccount(@Query(JioConstants.ParamQuery.TOKEN) String token,
@Query(JioConstants.ParamQuery.USER_ID) long userID,
@Query(JioConstants.ParamQuery.FIRST_NAME) String firstName,
@Query(JioConstants.ParamQuery.LAST_NAME) String lastName,
@Query(JioConstants.ParamQuery.GENDER) String gender,
@Query(JioConstants.ParamQuery.DOB) String dob,
@Query(JioConstants.ParamQuery.RELATIONSHIP_ID) long relationshipID,
@Query(JioConstants.ParamQuery.DISPLAY_UNIT) String displayUnit,
@Part("avatar\"; filename=\"picture.jpg\" ") RequestBody file);
和
RequestBody file = null;
if (mFileTemp != null) {
file = RequestBody.create(MediaType.parse("image/*"), mFileTemp);
} else {
file = RequestBody.create(MediaType.parse("image/*"), "");
}
manageCall(ServiceManager.INSTANCE2().
createDependentAccount(token, userID, firstName, lastName, gender, dob, relationshipID, displayUnit, file))
.enqueue(new SimplifiedCallback<CreateDependentAccountResponse>() {
@Override
public void success(CreateDependentAccountResponse data, String message) {
hideLoading();
祝你好运。 This is my game
不要使用@Multipart
。相反,使用这样的东西:
@POST("upload/image")
Observable<ResponseBody> uploadImage(@Body RequestBody body);
File imageFile = new File(path);
RequestBody body = RequestBody.create(MediaType.parse("image/jpeg"),imageFile);
api.uploadImage(body);
我正在制作一个应用程序,我必须在其中将图片从图库发送到服务器。
这些应该是 headers(根据养蜂场)。
Content-Type:image/jpeg
X-Filename:photo.jpg
但在拦截器的日志中,只有 X-Filename,尽管我尝试了多种方法,但我 运行 没有想法。
服务器响应 200 但下一次调用(提交图像)returns 500 在 post 结束时出错。
这些是方法:
@Multipart
@POST("uploads")
Observable<String> uploadImage(
@Header("Content-Type") String contentType,
@Header("X-Filename") String fileName,
@Header("Authorization") String token,
@Part MultipartBody.Part file
);
@GET("uploads/{fileId}/commit")
Observable<String> commitFile(
@Header("Content-Type") String type,
@Header("Authorization") String token,
@Path("fileId") String fileId
);
OkHttp 客户端:
private OkHttpClient createApiClient(Context context) {
int cacheSize = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(context.getCacheDir(), cacheSize);
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(chain -> {
Request request = chain.request().newBuilder().build();
request.newBuilder().addHeader("Content-Type", "application/json");
Timber.d("Request: [%s] %s", request.method(), request.url());
Timber.d("Request: %s", request.headers().toString());
if (request.body() != null) {
Timber.d("Request: %s", request.body().toString());
}
return chain.proceed(request);
});
builder.cache(cache);
return builder.build();
}
生成的日志:
D/NetModule: Request: [POST] https://winged-guild-133523.appspot.com/api/v1/uploads
D/NetModule: Request: X-Filename: asura.png
Authorization: HAYVi3clcqjug53IPS6AYMgzCPGnDE3Si
D/NetModule: Request: retrofit2.RequestBuilder$ContentTypeOverridingRequestBody@7c37f46
Postman 也会发生同样的事情 - Postman screenshot
提交失败并出现此错误:(抱歉格式丑陋)
{
"errorCode": "ImagesServiceFailureException",
"errorParam": "",
"errorMessage":"com.google.appengine.api.images.ImagesServiceFailureException: "
}
正如我所说,我 运行 没有想法,非常感谢任何有关此上传问题的帮助。
(edit) PS: 通过省略 @Header("Content-Type") String contentType在app中,在Postman中使用application/x-www-form-urlencoded,图片上传和提交都成功,但返回的图片url没有元数据,因此无法显示.
这是我使用改造的代码
@Multipart
@POST(ServiceConfig.API_CREATE_DEPENDENT_ACCOUNT)
@Headers({
"Accept: application/json",
"Accept-Encoding: gzip"
})
Call<DataResponse<CreateDependentAccountResponse>> createDependentAccount(@Query(JioConstants.ParamQuery.TOKEN) String token,
@Query(JioConstants.ParamQuery.USER_ID) long userID,
@Query(JioConstants.ParamQuery.FIRST_NAME) String firstName,
@Query(JioConstants.ParamQuery.LAST_NAME) String lastName,
@Query(JioConstants.ParamQuery.GENDER) String gender,
@Query(JioConstants.ParamQuery.DOB) String dob,
@Query(JioConstants.ParamQuery.RELATIONSHIP_ID) long relationshipID,
@Query(JioConstants.ParamQuery.DISPLAY_UNIT) String displayUnit,
@Part("avatar\"; filename=\"picture.jpg\" ") RequestBody file);
和
RequestBody file = null;
if (mFileTemp != null) {
file = RequestBody.create(MediaType.parse("image/*"), mFileTemp);
} else {
file = RequestBody.create(MediaType.parse("image/*"), "");
}
manageCall(ServiceManager.INSTANCE2().
createDependentAccount(token, userID, firstName, lastName, gender, dob, relationshipID, displayUnit, file))
.enqueue(new SimplifiedCallback<CreateDependentAccountResponse>() {
@Override
public void success(CreateDependentAccountResponse data, String message) {
hideLoading();
祝你好运。 This is my game
不要使用@Multipart
。相反,使用这样的东西:
@POST("upload/image")
Observable<ResponseBody> uploadImage(@Body RequestBody body);
File imageFile = new File(path);
RequestBody body = RequestBody.create(MediaType.parse("image/jpeg"),imageFile);
api.uploadImage(body);