2016-04-15 38 views
8

Tôi đang cố gắng tải tệp (hình ảnh) lên máy chủ bằng cách sử dụng Retrofit 2. Tôi sau đó tutorial mà dường như khá dễ dàng lúc đầu, nhưng đã không làm việc trong trường hợp của tôi ...Lỗi tải lên tệp bằng Retrofit 2

Khi tôi gọi hàm API, tôi luôn nhận được lỗi này:

W/System.err: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1 
W/System.err:  at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:190) 
W/System.err:  at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:166) 
W/System.err:  at retrofit2.Retrofit$1.invoke(Retrofit.java:145) 
W/System.err:  at java.lang.reflect.Proxy.invoke(Proxy.java:393) 
W/System.err:  at com.plante.android.cobalt.fragment.FragmentIncidentPlan.uploadFile(FragmentIncidentPlan.java:575) 

đây là cuộc gọi API của tôi:

@Multipart 
@POST(Constants.URL_UPLOAD) 
Call<ResponseBody> upload(@Part RequestBody description, 
          @Part MultipartBody.Part file); 

Dưới đây là phương pháp tôi sử dụng để tải lên một tập tin:

private void uploadFile(String path) { 
    // create upload service client 

    // use the FileUtils to get the actual file by uri 
    File file = new File(path); 
    Log.e(TAG, file.getAbsolutePath()); 

    // create RequestBody instance from file 
    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("picture", file.getName(), requestFile); 

    // add another part within the multipart request 
    String descriptionString = "hello, this is description speaking"; 
    RequestBody description = 
      RequestBody.create(
        MediaType.parse("multipart/form-data"), descriptionString); 

    // finally, execute the request 
    Call<ResponseBody> call = cobaltServices.upload(description, body); 
    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()); 
     } 
    }); 
} 
+0

Kiểm tra dòng 575 của 'FragmentIncidentPlan.java' bạn đang sử dụng một mảng mà đi ngoài giới hạn của nó. – Exaqt

+0

@Exaqt Dòng đó nằm trong câu hỏi của tôi: Gọi call = cobaltServices.upload (mô tả, nội dung); – Jaythaking

Trả lời

3

tôi khắc phục vấn đề của tôi sử dụng liên kết này: https://github.com/square/retrofit/issues/1063#issuecomment-145920568

Đây là giải pháp của vấn đề:

@Multipart 
@POST ("/api/Events/editevent") 
Call<Event> editEvent (@PartMap Map<String, RequestBody> params); 

tôi gọi nó bằng cách làm theo cách.

Map<String, RequestBody> map = new HashMap<>(); 
map.put("Id", AZUtils.toRequestBody(eventId)); 
map.put("Name", AZUtils.toRequestBody(titleView.getValue())); 

if (imageUri != null) { 
     File file = new File(imageUri.getPath()); 
     RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), file); 
     map.put("file\"; filename=\"pp.png\"", fileBody); 
} 

Call<Event> call = api.editEvent(map); 
call.enqueue(new Callback<Event>() { } 

Phương pháp toRequestBody chỉ chuyển đổi chuỗi thành RequestBody

public static RequestBody toRequestBody (String value) { 
    RequestBody body = RequestBody.create(MediaType.parse("text/plain"), value); 
    return body ; 
} 
6

Ngoại lệ cho biết rằng @Part đầu tiên không cần tên trong chú thích.

@Multipart 
@POST(Constants.URL_UPLOAD) 
Call<ResponseBody> upload(@Part RequestBody description, 
          @Part MultipartBody.Part file); 
+0

Tôi đã cập nhật câu hỏi của mình với lỗi mới sau khi xóa phần Mô tả ... – Jaythaking

+3

'@Thông số khởi động bằng MultipartBody.Part không được bao gồm tên phần trong chú thích.' nói rằng bạn không nên sử dụng tên. Vì vậy, nó phải là '@ Part' thay vì' @Part ("description") ' – Exaqt

+0

Có lỗi tôi đã chỉnh sửa chú thích của mình ... – Jaythaking