RetrofitError: expected 329 bytes but received 4096 in Android

RetrofitError: expected 329 bytes but received 4096 in Android

我是 Retrofit 的新手,在我的应用程序中,我正在尝试使用 Retrofit 从画廊向服务器发送图像,但我在 Retrofit 的失败方法中收到“RetrofitError: expected 329 bytes but received 4096”响应.我正在根据 onAvtivityResult 中的意图创建位图,并使用路径作为名称和位图制作文件对象。

    Uri mImgUri = returnedIntent.getData();
                InputStream imageStream = getContentResolver().openInputStream(mImgUri);
                final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);

                    This is the error log,

                    retrofit.RetrofitError: expected 329 bytes but received 4096
                                at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:395)
                                at retrofit.RestAdapter$RestHandler.access0(RestAdapter.java:220)
                                at retrofit.RestAdapter$RestHandler.obtainResponse(RestAdapter.java:278)
                                at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
                                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
                                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
                                at retrofit.Platform$Android.run(Platform.java:142)
                                at java.lang.Thread.run(Thread.java:856)
                         Caused by: java.net.ProtocolException: expected 329 bytes but received 4096
                                at com.squareup.okhttp.internal.http.HttpConnection$FixedLengthSink.write(HttpConnection.java:299)
                                at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:133)
                                at okio.RealBufferedSink.write(RealBufferedSink.java:148)
                                at retrofit.mime.TypedFile.writeTo(TypedFile.java:78)

                This is my Retrofit adapter,

                private void startRetrofitTask(Bitmap mBitmap,Uri mImgUri){

                        String mimeType = "image/png";
                        File mFile = AppUtils.convertBitmapToFile(this,mImgUri.getLastPathSegment(),mBitmap);
                        TypedFile fileToSend = null;
                        RestAdapter restAdapter = new RestAdapter.Builder()
                                .setEndpoint(Constants.LOCAL_BASE_URL)
                                .setClient(new OkClient(new OkHttpClient()))
                                .build();
                        RetrofitCommonService mRetrofitCommonService = restAdapter.create(RetrofitCommonService.class);

                        if(mFile != null){
                           fileToSend = new TypedFile(mimeType, mFile);
                        }
                        mRetrofitCommonService.upLoadImage(new AppUtils(this).getPhone(),
                                getDeviceId(), fileToSend,this);
                    }


            public static File convertBitmapToFile(Context mContext,String mName,Bitmap bitmap) {
                    if(bitmap == null)return null;
                    File filesDir = mContext.getFilesDir();
                    File imageFile = new File(filesDir, mName + ".png");
                    OutputStream os;
                    try {
                        os = new FileOutputStream(imageFile);
                        bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
                        os.flush();
                        os.close();
                    } catch (Exception e) {
                        Log.e("TAG", "Error writing bitmap", e);
                    }
                    return imageFile;
                }


         @Multipart
            @POST("/user/asset")
            @Headers("Accept:application/json")
            void upLoadImage(@Header("mobile-number") String mPhone, @Header("uid") String imei,
                                   @Part("file") TypedFile mBody,Callback<RetrofitResponse> response);

我不知道你为什么要将位图 uri 转换为文件。像这样从 URI 和 post 中获取照片 URL 字符串。而已。

对我来说效果很好!!!

适配器设置 & post:

 restPhotoAdapter = new RestAdapter.Builder()
            .setClient(new OkClient(okHttpClient))
            .setEndpoint(Config.BASE_API_PHOTO_URL)
            .setLogLevel((BuildConfig.DEBUG) ? RestAdapter.LogLevel.FULL : RestAdapter.LogLevel.NONE)
            .build();


 public void postPhoto(final String url,
                              final ControllerCallback<List<Photo>> postRequestCallback) {
    TypedFile file = new TypedFile("image/jpeg", new File(url));
    Repository repository = restPhotoAdapter.create(Repository.class);
    repository.postPhoto(file, new Callback<List<Photo>>() {
        @Override
        public void success(List<Photo> photoOut, Response response) {
            postRequestCallback.success(photoOut);
        }

        @Override
        public void failure(RetrofitError error) {
            postRequestCallback.failure(new CustomError(error));
        }
    });
}
        @chain thanks for the response and it worked for me, 
and i have done some change in my code for making file from Uri and it really worked. 


    TypedFile fileToSend = new TypedFile("image/png", new File(AppUtils.getRealPathFromURI(context, mImgUri)));


        public static String getRealPathFromURI(Context context,Uri contentURI) {
                String result;
                Cursor cursor = context.getContentResolver().query(contentURI, null, null, null, null);
                if (cursor == null) { // Source is Dropbox or other similar local file path
                    result = contentURI.getPath();
                } else {
                    cursor.moveToFirst();
                    int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
                    result = cursor.getString(idx);
                    cursor.close();
                }
                return result;
            }

我通过在 urlConnection.getOutputStream() 之前设置 urlConnection setFixedLengthStreamingMode() 解决了这种错误。

您需要指定字节长度以避免不匹配。

byte[] buf = jsonString.getBytes("UTF-8");
urlConnection.setFixedLengthStreamingMode(buf.length);

DataOutputStream os = new DataOutputStream(urlConnection.getOutputStream());

os.write(buf, 0, buf.length);
os.flush();
os.close();