简体   繁体   English

使用retrofit2上传照片:改装:2.0.0-beta4

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM