[英]upload photo with retrofit2: retrofit: 2.0.0-beta4
I have problem with upload photo on server with uses retrofit 2.Can somebody help me? 我在使用改造的服务器上上传照片有问题2.可以有人帮助我吗? what i did wrong?
我做错了什么? my back-end dev has sad me that boundary in header didnt generate =( this is my interface:
我的后端开发让我很遗憾,标题中的边界没有生成=(这是我的界面:
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.Call;
import retrofit2.http.Multipart;
import okhttp3.MultipartBody;
import com.google.gson.JsonElement;
public interface Retrofitv2Api {
@Multipart
@Headers("Content-Type: multipart/form-data;")
@POST("/mobile/v1/classifieds/UploadImage")
Call<JsonElement> UploadImage(@Part MultipartBody.Part body,@Part("uniqId")String uniqId,@Part("token")String token);}
builder: 制造商:
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitV2Config {
private static Retrofit getRetrofit(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.qrz.ru")
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
}
public static Retrofitv2Api getService(){
return getRetrofit().create(Retrofitv2Api.class);
}
and upload fragment: 并上传片段:
String photoPath = photoAdapter.getPhotoPaths().get(0);
File image = new File(photoPath);
RequestBody imageBody = RequestBody.create(MediaType.parse("image/*"), image);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", image.getName(), imageBody);
RetrofitV2Config.getService().UploadImage(body , "2536654", Token.getSavedToken()).enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
Log.i(Logger.TAG, "onResponseUpload " + response.body() + " " + response.code());
}
@Override
public void onFailure(Call<JsonElement> call, Throwable t) {
Log.i(Logger.TAG, "onFailureUpload");
}
});
backend ansver: 后端ansver:
21:34:32.386117 IP 46.37.203.69.50461 > 62.181.46.35.http: Flags [P.], seq 1184070465:1184071311, ack 3418438796, win 65535, length 846
E..v.o@.5....%.E>..#...PF.{A..<.P...]...POST /mobile/v1/classifieds/UploadImage HTTP/1.1
Content-Type: multipart/form-data
Content-Length: 647
Host: api.qrz.ru
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/3.2.0
--950f42dd-12a1-4e11-a3b0-826ddaf41aa3
Content-Disposition: form-data; name="img"
Content-Transfer-Encoding: binary
Content-Type: application/json; charset=UTF-8
Content-Length: 2
{}
--950f42dd-12a1-4e11-a3b0-826ddaf41aa3
Content-Disposition: form-data; name="uniqId"
Content-Transfer-Encoding: binary
Content-Type: application/json; charset=UTF-8
Content-Length: 8
"215132"
--950f42dd-12a1-4e11-a3b0-826ddaf41aa3
Content-Disposition: form-data; name="token"
Content-Transfer-Encoding: binary
Content-Type: application/json; charset=UTF-8
Content-Length: 22
Thank you all ! 谢谢你们 ! I find the solution.In my case I should use MultipartBody.Part instead String in interface Retrofitv2Api
我找到了解决方案。在我的情况下,我应该在界面Retrofitv2Api中使用MultipartBody.Part而不是String
public interface Retrofitv2Api {
@Multipart
@POST("/mobile/v1/classifieds/UploadImage")
Call<UploadPhoto> UploadImage(@Part MultipartBody.Part body,@Part MultipartBody.Part uniqId,@Part MultipartBody.Part token);}
File image = new File(path);
RequestBody imageBody = RequestBody.create(MediaType.parse("image/jpeg"), image);
MultipartBody.Part body = MultipartBody.Part.createFormData("img", image.getName(), imageBody);
MultipartBody.Part uniqID = MultipartBody.Part.createFormData("uniqId", uniqId);
MultipartBody.Part token = MultipartBody.Part.createFormData("token", Token.getSavedToken());
Call<UploadPhoto> call = RetrofitV2Config.getService().UploadImage(body, uniqID, token);
call.enqueue(new Callback<UploadPhoto>() {
@Override
public void onResponse(Call<UploadPhoto> call,
Response<UploadPhoto> response) {
Log.v("Upload", "success: " + response.raw().toString());
}
@Override
public void onFailure(Call<UploadPhoto> call, Throwable t) {
Log.e("Upload error:", t.getMessage());
}
});
Try to use TypedFile
instead MultipartBody
, something like this: 尝试使用
TypedFile
而不是MultipartBody
,如下所示:
String photoPath = photoAdapter.getPhotoPaths().get(0);
try {
File image = new File(getApplicationContext().getFilesDir().getPath().toString(), "YourFileName");
// Decode with inSampleSize
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inSampleSize = calculateInSampleSize(bitmapOptions, 1080, 1080);
bitmapOptions.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFile(photoPath, bitmapOptions);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, bos);
byte[] bitmapdata = bos.toByteArray();
//write the bytes in file
FileOutputStream fos = new FileOutputStream(image);
fos.write(bitmapdata);
fos.flush();
fos.close();
// yourImageType means for example .png .jpg etc.
TypedFile typedFile = new TypedFile("image/yourImageType", image);
} catch (IOException e) {
} catch (OutOfMemoryError outOfMemoryError) {
}
RetrofitV2Config.getService().UploadImage(typedFile , "2536654", Token.getSavedToken()).enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
Log.i(Logger.TAG, "onResponseUpload " + response.body() + " " + response.code());
}
@Override
public void onFailure(Call<JsonElement> call, Throwable t) {
Log.i(Logger.TAG, "onFailureUpload");
}
});
And change your interface: 并改变你的界面:
@Multipart
@Headers("Content-Type: multipart/form-data;")
@POST("/mobile/v1/classifieds/UploadImage")
Call<JsonElement> UploadImage(@Part("file") TypedFile file,@Part("uniqId")String uniqId,@Part("token")String token);}
public interface UploadAvatarService {
@Multipart
@POST("user/upload_head")
Observable<UploadAvatarBean> upload(@Part("file\"; filename=\"image.png\"") RequestBody avatarFile);
}
the Part
will code in Retrofit as 该
Part
将在Retrofit中编码为
Headers headers =
Headers.of("Content-Disposition", "form-data; name=\"" + partName + "\"",
"Content-Transfer-Encoding", part.encoding());
you need set filename to the file. 你需要设置文件名到文件。
You should use RequestBody instead String 您应该使用RequestBody而不是String
public interface Retrofitv2Api {
@Multipart
@Headers("Content-Type: multipart/form-data;")
@POST("/mobile/v1/classifieds/UploadImage")
Call<JsonElement> UploadImage(@Part MultipartBody.Part body,@Part("uniqId")RequestBody uniqId,@Part("token") RequestBody token);
}
private void UploadImage(File file,String uniqId,String token) {
// create upload service client
Retrofitv2Api service =
new RetrofitV2Config().getService();
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
MultipartBody.Part.createFormData("file", file.getName(), requestFile);
// finally, execute the request
Call<ResponseBody> call = service.upload( body,RequestBody.create(
MediaType.parse("multipart/form-data"), uniqId),RequestBody.create(
MediaType.parse("multipart/form-data"), token));
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call,
Response<ResponseBody> response) {
Log.v("Upload", "success");
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e("Upload error:", t.getMessage());
}
});
} }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.