2017-06-30 9 views
6

मैं रेट्रोफिट 2 के माध्यम से एक मल्टीपार्ट पोस्ट अनुरोध करने की कोशिश कर रहा हूं, जहां मैं एपीआई को एक कस्टम फ़ाइल अपलोड करता हूं।रेट्रोफिट। java.net.ProtocolException: अपेक्षित * बाइट्स लेकिन प्राप्त *

यह बेतरतीब ढंग से इस अपवाद के साथ विफल:

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

किसी को भी इस पर कुछ प्रकाश डाल सकता है करता है?

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

निर्माता में:

इस इंटरफ़ेस में मेरी कोड है

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); 
} 

और अपलोड विधि में:

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(); 
     } 
    }); 
} 

उत्तर

1

थोड़ी देर के लिए अध्ययन कर समस्या मैंने महसूस किया गया है किया गया था कि फ़ाइल की सामग्री हमेशा बदलता रहता है (क्योंकि यह एक सेंसर का उत्पादन होता है) के बाद।

इसका मतलब है कि फ़ाइल है कि सिर और शरीर के एक ही डेटा न हो (इसलिए अलग लंबाई) है, जो बेमेल के कारण होता है के लिए फ़ाइल के लिए जाँच की है।

मैंने फ़ाइल के creating a copy को हल किया और मूल फ़ाइल के बजाय इसे (प्रतिलिपि) भेज दिया।

1

यहाँ मैं सभी के लिए उपयोग है मेरे अनुरोध और कोई समस्या नहीं है। मुझे बताएं कि यह आपके लिए काम नहीं करता है। मुझे लगता है कि आपकी फ़ाइल के लिए पोस्ट नाम "फ़ाइल" है।

प्रोटोकॉल में:

@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()); 
     } 
}); 

पुनश्च: आप के बाद से यह एक के बजाय फाइलों का एक नक्शा स्वीकार करता है, एकाधिक फ़ाइलों को अपलोड करने के लिए कोड के इस टुकड़े का उपयोग कर सकते एक दस्तावेज।

पीएस # 2: इस विधि के साथ कई समस्याओं के कारण, मुझे यह सुनिश्चित करने के लिए नीचे कोड जोड़ना पड़ा कि यह कभी भी खाली या खाली नक्शा नहीं भेजता।

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

"@Part" के बजाय एनोटेशन "@PartMap" का उपयोग करके समस्या हल हो गई। – kike

+0

क्या आप कृपया इस उत्तर में call.enqueue() जोड़ सकते हैं ताकि एक ही समस्या वाले लोगों को कोड का एक कामकाजी टुकड़ा हो सके? – kike

+1

@kike मैंने अपना जवाब बदल दिया है और यह भी जोड़ा है कि फाइलों के अलावा स्ट्रिंग कैसे भेजें। –

2

जब मैं रिकॉर्डिंग अपलोड करने का प्रयास कर रहा था तो मुझे इस समस्या का सामना करना पड़ा। फ़ाइल अपलोड करने के लिए वेब सेवा को कॉल करने से पहले मैंने रिकॉर्डिंग प्रक्रिया को रोककर हल किया।

objMediaRecorder.stop(); 
objMediaRecorder.release(); 
objMediaRecorder = null; 
संबंधित मुद्दे