我正在尝试使用 Retrofit 2.0对服务器进行 HTTP POST
MediaType MEDIA_TYPE_TEXT = MediaType.parse("text/plain"); MediaType MEDIA_TYPE_IMAGE = MediaType.parse("image/*"); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); imageBitmap.compress(Bitmap.CompressFormat.JPEG,90,byteArrayOutputStream); profilePictureByte = byteArrayOutputStream.toByteArray(); Call<APIResults> call = ServiceAPI.updateProfile( RequestBody.create(MEDIA_TYPE_TEXT, emailString), RequestBody.create(MEDIA_TYPE_IMAGE, profilePictureByte)); call.enqueue();
服务器返回一个错误,指出该文件无效。
这很奇怪,因为我尝试在 iOS 上上传相同格式的相同文件(使用其他库),但上传成功。
我想知道使用 Retrofit 2.0 上传图片的正确方法是什么?
在上传之前我应该先将其保存到磁盘吗?
PS:我已经对其他不包含图像的多部分请求进行了改造,并且他们成功完成了。问题是当我试图在正文中包含一个字节时。
我强调 1.9 和 2.0 中的解决方案,因为它对某些人有用
在1.9中,我认为更好的解决方案是将文件保存到磁盘并将其用作 Typed 文件,例如:
1.9
(我不知道你的服务器端实现)有一个类似于这个的API接口方法
@POST("/en/Api/Results/UploadFile") void UploadFile(@Part("file") TypedFile file, @Part("folder") String folder, Callback<Response> callback);
并像使用它一样
TypedFile file = new TypedFile("multipart/form-data", new File(path));
中问题的解决方法,现在已修复,正确的方法请参考jimmy0251 的答案)
API接口:
public interface ApiInterface { @Multipart @POST("/api/Accounts/editaccount") Call<User> editUser(@Header("Authorization") String authorization, @Part("file\"; filename=\"pp.png\" ") RequestBody file, @Part("FirstName") RequestBody fname, @Part("Id") RequestBody id); }
像这样使用它:
File file = new File(imageUri.getPath()); RequestBody fbody = RequestBody.create(MediaType.parse("image/*"), file); RequestBody name = RequestBody.create(MediaType.parse("text/plain"), firstNameField.getText() .toString()); RequestBody id = RequestBody.create(MediaType.parse("text/plain"), AZUtils.getUserId(this)); Call<User> call = client.editUser(AZUtils.getToken(this), fbody, name, id); call.enqueue(new Callback<User>() { @Override public void onResponse(retrofit.Response<User> response, Retrofit retrofit) { AZUtils.printObject(response.body()); } @Override public void onFailure(Throwable t) { t.printStackTrace(); } });