2015-11-02 13 views
5

Square Retrofit version 2.0 beta2 kullanıyorum. this tutorial .'u izlemeye çalıştım Sunucuya bir bitmap görüntüsü yüklemeye çalışıyorum ama bir şekilde kod çalışmıyor. Postacı kullanarak sunucumu test etmeyi denedim ve fotoğraf gönderip alabiliyorum. İşte flask denetleyicim.Retrofit (2.0 beta2) Çoklu dosya yükleme işlemi çalışmıyor

@app.route('/api/photo/user/<int:user_id>', methods=["POST"]) 
    def post_user_photo(user_id): 
     app.logger.info("post_user_photo=> user_id:{}, photo: {}".format(
      user_id, 
      request.files['photo'].filename, 
     )) 
     user = User.query.get_or_404(user_id) 
     try: 
      user.photo = request.files['photo'].read() 
     except Exception as e: 
      app.logger.exception(e) 
      db.session.rollback() 
      raise 
     db.session.commit() 
     return "", codes.no_content 

Denetleyicimi test etmek için postacıyı kullandım ve işte postacı tarafından oluşturulan istek var.

POST /api/photo/user/5 HTTP/1.1 
Host: blooming-cliffs-9672.herokuapp.com 
Cache-Control: no-cache 
Postman-Token: 8117fb79-4781-449d-7d22-237c49b53389 
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW 

----WebKitFormBoundary7MA4YWxkTrZu0gW 
Content-Disposition: form-data; name="photo"; filename="sfsu.jpg" 
Content-Type: image/jpeg 


----WebKitFormBoundary7MA4YWxkTrZu0gW 

Uyarlama hizmetini tanımladım ve görüntüyü yüklemek için burada Android kodum var. Arayüz kısmı

@Multipart 
    @POST("/api/photo/user/{userId}") 
    Call<Void> uploadUserProfilePhoto(@Path("userId") Integer userId, @Part("photo") RequestBody photo); 

Burada istemci oluşturucu bölümü burada

public static BeamItService getService(){ 
     if (service == null) { 
      OkHttpClient client = new OkHttpClient(); 
      HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); 
      interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); 
      HttpLoggingInterceptor interceptor2 = new HttpLoggingInterceptor(); 
      interceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS); 

      client.interceptors().add(interceptor); 
      client.interceptors().add(interceptor2); 

      service = new Retrofit.Builder() 
        .baseUrl(BASE_URL) 
        .client(client) 
        .addConverterFactory(GsonConverterFactory.create()) 
        .build().create(BeamItService.class); 
     } 
     return service; 
    } 

Ve bitmap yüklemek için çalışır Android etkinlik kodudur.

private void uploadProfilePhoto(){ 
     BeamItService service = BeamItServiceTransport.getService(); 

     MediaType MEDIA_TYPE_PNG = MediaType.parse("image/jpeg"); 
     byte [] data = BitmapUtility.getBitmapToBytes(((BitmapDrawable) ivProfilePhoto.getDrawable()).getBitmap()); 
     Log.d(TAG, String.format("Profile detals => user_id: %d, size of data: %d", 5, data.length)); 

     RequestBody requestBody1 = RequestBody.create(MEDIA_TYPE_PNG, 
                data); 
     Log.d(TAG, "requestBody: " + requestBody1.toString()); 
     RequestBody requestBody2 = new MultipartBuilder() 
       .type(MultipartBuilder.FORM) 
       .addPart(Headers.of("Content-Disposition", "form-data; name=\"photo\"; filename=\"t.jpg\""), 
         requestBody1) 
       .build(); 
     Log.d(TAG, "requestBody: " + requestBody2.toString()); 
//  ProfileDetails profileDetails = new DBHelper(this).fetchProfileDetails(); 

     Call<Void> call = service.uploadUserProfilePhoto(5, requestBody2); 
     call.enqueue(new ProfilePhotoUploadCallback()); 
    } 

    private class ProfilePhotoUploadCallback implements Callback<Void> { 

     @Override 
     public void onResponse(Response<Void> response, Retrofit retrofit) { 
      Log.d(TAG, String.format("ProfilePhotoUploadCallback=> code: %d", response.code())); 
     } 

     @Override 
     public void onFailure(Throwable t) { 

     } 
    } 

Ancak, yükleme başarısız olduğunda, uygulama her seferinde uygulama kodu durum kodu 400'ü döndürür. Baloncu uygulamasında kesme noktasını koymaya çalıştım, ancak istek oraya bile ulaşmıyor. burada ben de güçlendirme intercepter etkinleştirmek ve isteği ve yanıtını log çalıştı sunucusu günlük

2015-11-02T06:05:42.288574+00:00 heroku[router]: at=info method=POST path="/api/photo/user/5" host=blooming-cliffs-9672.herokuapp.com request_id=2cc8b6c8-f12a-4e4b-8279-cedfc39712f2 fwd="204.28.113.240" dyno=web.1 connect=1ms service=88ms status=400 bytes=347 
2015-11-02T06:05:42.209347+00:00 app[web.1]: [2015-11-02 06:05:42 +0000] [11] [DEBUG] POST /api/photo/user/5 

, ama tüm POST isteği vücudu alamadım. İşte Android günlüğü.

11-02 00:24:22.119 3904-4382/com.contactsharing.beamit D/OkHttp: --> POST /api/photo/user/5 HTTP/1.1 
11-02 00:24:22.119 3904-4382/com.contactsharing.beamit D/OkHttp: Content-Type: multipart/form-data; boundary=4031e177-0e4b-4f16-abe8-20c54e506846 
11-02 00:24:22.120 3904-4382/com.contactsharing.beamit D/OkHttp: Content-Length: 17171 
11-02 00:24:22.120 3904-4382/com.contactsharing.beamit D/OkHttp: Host: blooming-cliffs-9672.herokuapp.com 
11-02 00:24:22.120 3904-4382/com.contactsharing.beamit D/OkHttp: Connection: Keep-Alive 
11-02 00:24:22.120 3904-4382/com.contactsharing.beamit D/OkHttp: Accept-Encoding: gzip 
11-02 00:24:22.120 3904-4382/com.contactsharing.beamit D/OkHttp: User-Agent: okhttp/2.6.0-SNAPSHOT 
11-02 00:24:22.120 3904-4382/com.contactsharing.beamit D/OkHttp: --> END POST 
11-02 00:24:22.179 3904-4537/com.contactsharing.beamit I/DBHelper: Updated row: 1 
11-02 00:24:22.316 3904-4382/com.contactsharing.beamit D/OkHttp: <-- HTTP/1.1 400 BAD REQUEST (195ms) 
11-02 00:24:22.316 3904-4382/com.contactsharing.beamit D/OkHttp: Connection: keep-alive 
11-02 00:24:22.316 3904-4382/com.contactsharing.beamit D/OkHttp: Server: gunicorn/19.3.0 
11-02 00:24:22.316 3904-4382/com.contactsharing.beamit D/OkHttp: Date: Mon, 02 Nov 2015 08:24:22 GMT 
11-02 00:24:22.316 3904-4382/com.contactsharing.beamit D/OkHttp: Content-Type: text/html 
11-02 00:24:22.316 3904-4382/com.contactsharing.beamit D/OkHttp: Content-Length: 192 
11-02 00:24:22.316 3904-4382/com.contactsharing.beamit D/OkHttp: Via: 1.1 vegur 
11-02 00:24:22.316 3904-4382/com.contactsharing.beamit D/OkHttp: OkHttp-Selected-Protocol: http/1.1 
11-02 00:24:22.316 3904-4382/com.contactsharing.beamit D/OkHttp: OkHttp-Sent-Millis: 1446452662120 
11-02 00:24:22.316 3904-4382/com.contactsharing.beamit D/OkHttp: OkHttp-Received-Millis: 1446452662316 
11-02 00:24:22.316 3904-4382/com.contactsharing.beamit D/OkHttp: <-- END HTTP 

Lütfen yardım edin, takılıyorum ve herhangi bir ilerleme kaydedemiyorum.

cevap

11

Burada bir çok parçalı istek gövdesi yerleştiriyorsunuz (Çok parçalı bir multipart).

Son zamanlarda benzer bir uygulama gerçekleştirdiyseniz, @Multipart ve @Part kullanmak yerine @Body'u MultipartBuilder ile kullanabilirsiniz.

@POST("/api/photo/user/{userId}") 
Call<Void> uploadUserProfilePhoto(@Path("userId") Integer userId, @Body RequestBody photo); 

Sonra yerine MultipartBuilder.addPart(...) kullanımını MultipartBuilder.addFormDataPart(name, filename, requestBody)

private void uploadProfilePhoto() { 
    BeamItService service = BeamItServiceTransport.getService(); 

    MediaType MEDIA_TYPE_PNG = MediaType.parse("image/jpeg"); 
    byte [] data = BitmapUtility.getBitmapToBytes(((BitmapDrawable) ivProfilePhoto.getDrawable()).getBitmap()); 
    Log.d(TAG, String.format("Profile detals => user_id: %d, size of data: %d", 5, data.length)); 

    RequestBody requestBody1 = RequestBody.create(MEDIA_TYPE_PNG, data); 
    Log.d(TAG, "requestBody: " + requestBody1.toString()); 
    RequestBody requestBody2 = new MultipartBuilder() 
      .type(MultipartBuilder.FORM) 
      .addFormDataPart("photo", "t.jpg", requestBody1) 
      .build(); 
    Log.d(TAG, "requestBody: " + requestBody2.toString()); 
// ProfileDetails profileDetails = new DBHelper(this).fetchProfileDetails(); 

    Call<Void> call = service.uploadUserProfilePhoto(5, requestBody2); 
    call.enqueue(new ProfilePhotoUploadCallback()); 
} 
+0

kullanmanın bir çekicilik teşekkür gibi bir çok çalıştı. Günümü kurtardın. –

+0

Evet, benim için de çalıştı. Çok teşekkürler! – Kaizie

+0

Çok teşekkür ederim. Benim günümü kurtardın :) –