2015-11-02 5 views
5

Square Retrofitバージョン2.0 beta2を使用しています。私は従うことを試みたthis tutorial .私はサーバーにビットマップイメージをアップロードしようとしていますが、何とかコードが動作していません。私は郵便配達員を使用して私のサーバーをテストしようとしました。写真を投稿して検索することもできました。ここにフラスココントローラがあります。私はここに私のコントローラをテストするために郵便配達を使用しているRetrofit(2.0 beta2)マルチパートファイルのアップロードが機能しない

@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 

は郵便配達によって生成された要求です。

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 

私はretrofitサービスと画像のアップロードを定義しました。ここに私のAndroidコードがあります。インターフェイスの一部

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

ここでは、クライアントビルダーの一部で、ここで

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

とは、ビットマップをアップロードしようとするAndroidのアクティビティコードです。

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) { 

     } 
    } 

アップロードに失敗した場合、フラスコアプリは毎回ステータスコード400を返します。私はフラスコのアプリケーションにブレークポイントを入れようとしましたが、要求はそこに届かない。 は、ここで私はまた、レトロフィットintercepterを有効にし、要求と応答をログに記録しようとしたサーバーのログ

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 

ですが、私は全体のPOSTリクエストのボディを得ることはありません。ここにAndroidのログがあります。

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 

私は立ち往生しており、何も進めません。

答えて

11

ここでは、マルチパートリクエストボディをネストしています(マルチパート内のマルチパート)。

@Multipart@Partの代わりに@BodyMultipartBuilderを使用すると、最近類似したものが実装されています。その後

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

代わりの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

MultipartBuilder.addPart(...)使用を使用してそれはどうもありがとう魅力のように働きました。あなたは私の一日を救った。 –

+0

はい、それは私のために働いた。どうもありがとう! – Kaizie

+0

ありがとうございました!あなたは私の日を救った:) –

関連する問題