Modified. java.net.ProtocolException: expected * bytes but received *

I am trying to execute a Multipart POST request through Retrofit2, where I load my own file in the API.

It randomly fails with this exception:

W/System.err: java.net.ProtocolException: expected 154 bytes but received 634

Can anyone tell about him?

This is my code in the interface:

@Multipart
@POST("recordings/{id}/{rec_id}/")
Call<ResponseBody> uploadRecording(@Path("id") String id, @Path("rec_id") String rec_id, @Part MultipartBody.Part bleFile);

In the constructor:

public ApiConnectionManager(Context con){
    Gson gson = new GsonBuilder()
            .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
            .create();

    OkHttpClient.Builder client = new OkHttpClient.Builder();
    HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
    loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    client.addInterceptor(loggingInterceptor);

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(con.getResources().getString(R.string.api_url)) // API url is hidden
            .addConverterFactory(GsonConverterFactory.create(gson))
            .client(client.build())
            .build();

    this.companyAPI = retrofit.create(CompanyAPI.class);
}

and in the boot method:

private void uploadFile(String id, final File bleFile) {
    MediaType MEDIA_TYPE = MediaType.parse("multipart/mixed");
    RequestBody requestBody = RequestBody.create(MEDIA_TYPE,bleFile);
    MultipartBody.Part partFile = MultipartBody.Part.createFormData("file", bleFile.getName(), requestBody);
    String recordingId = bleFile.getName().replace(".BLE","");
    Call<ResponseBody> call = companyAPI.uploadRecording(id, recordingId, partFile);
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            Log.d(TAG+"-Upload "+bleFile.getName(),response.message());
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            Log.d(TAG,"FAILED");
            t.printStackTrace();
        }
    });
}
+6
source share
3 answers

After some time studying the problem, I realized that the contents of the file always changed (since this is the result of the sensor).

This means that the file that is checked for HEAD and the file for BODY may not contain the same data (therefore different lengths), which caused a mismatch.

() .

+1

, . , , - .

objMediaRecorder.stop();
objMediaRecorder.release();
objMediaRecorder = null;
+2

. , . , POST "".

:

@Multipart
@POST
Call<ResponseBody> request(
        @Url String url, // Request URL
        @PartMap Map<String, String> vars, // POST Strings
        @PartMap Map<String, RequestBody> files // POST Files
);

:

Map<String, String> vars = new HashMap<>();
Map<String, RequestBody> files = new HashMap<>();

/** Put a string **/

vars.put("name", "value");

/** Put a file **/

String key = String.format(Locale.US, "file\"; filename=\"%s", file.getName());
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
files.put(key, requestBody);

/** Construct the call **/

Call<ResponseBody> call = mProtocol.request(url, vars, files);

call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            Log.d("Debug", response.body().string());
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            if (call.isCanceled()) Log.d("Debug", "Call Canceled");
            else Log.d("Debug", "Call Failed: " + t.toString());
        }
});

PS: , , .

PS # 2: - , , , , .

if (vars == null) {
    vars = new HashMap<>();
    vars.put("01110011", "01101101"); // put whatever you want
}
if (files == null) files = new HashMap<>();
+1

All Articles