2012-03-24 10 views
1

私はHttpClientとmimeを使用して、AndroidクライアントからCouchDBに画像ファイルを送信しています。 はしかし、このAndroidでCouchDBに画像を添付する方法は?

D/FormReviewer(4733): {"error":"bad_request","reason":"invalid UTF-8 JSON: <<45,45,103,75,66,70,69,104,121,102,121,106,72,66,101,80,\n 

のようないくつかのエラーメッセージがここに

final String ProfileBasicID = UUID.randomUUID().toString(); 

Data.postImage(IconFile, "http://spark.iriscouch.com/driver/"+ProfileBasicID,new Callback<String>()) 


public static void postImage(File image,String url, Callback<String> success) throws IOException { 
    HttpClient httpclient = new DefaultHttpClient(); 
    HttpPut method = new HttpPut(url); 

    try { 
     MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); 
     entity.addPart("type", new StringBody("photo")); 
     entity.addPart("form_file", new FileBody(image, "image/jpeg")); 
     method.setEntity(entity); 
     HttpResponse resp = httpclient.execute(method); 
     Log.d("httpPost", "Login form get: " + resp.getStatusLine()); 
     StatusLine statusLine = resp.getStatusLine(); 
     Log.d(tag, statusLine.toString()); 
     if (entity != null) { 
      entity.consumeContent(); 
     } 
     switch(resp.getStatusLine().getStatusCode()){ 
     case HttpStatus.SC_CREATED: 
      success.call(EntityUtils.toString(resp.getEntity())); 
      break; 
     default: 
      throw new ClientProtocolException(statusLine.toString() +"\n"+ EntityUtils.toString(resp.getEntity())); 
     } 
    } catch (Exception ex) { 
     Log.d("FormReviewer", "Upload failed: " + ex.getMessage() + 
      " Stacktrace: " + ex.getStackTrace()); 
    } finally { 
     // mDebugHandler.post(mFinishUpload); 
     httpclient.getConnectionManager().shutdown(); 
    } 
} 

は私の手を教えてください私のコードです

答えて

1

RIGHT、私は以前ここに掲載忘れおかげであります。 これは私が思ったほど簡単ではありません。私はあなたが読むことをお勧め いくつかのリンク:

  1. CouchDB Document API
  2. (Draft) Core API

[OK]をクリックします。 「スタンドアロン」または「インラインアタッチメント」を使用するかどうかを最初に決定します。現在のところ私はProとConが何であるか分かりませんが、あなたのコードに基づいていますが、私が行ったことは、 "Standalone"に行くことになります。

まず、イメージを添付するドキュメントのrev(リビジョン)番号が必要です。上記リンクあたりとして、そのドキュメントにHEADリクエストを実行して、次の操作を行います。

private String getParentRevision(String uuid, HttpClient httpClient) { 
String rev = ""; 
try { 
    HttpHead head = new HttpHead("http://192.168.56.101/testforms/" + uuid + "/"); 
    HttpResponse resp = httpClient.execute(head); 
    Header[] headers = resp.getAllHeaders(); 
    getLog().debug("Dumping headers from head request");; 
    for (Header header : headers) { 
    getLog().debug(header.getName() + "=" + header.getValue()); 
    if ("Etag".equals(header.getName())) { 
     StringBuilder arg = new StringBuilder(header.getValue()); 
     if (arg.charAt(0) == '"') { 
     arg.delete(0, 1); 
     } 
     if (arg.charAt(arg.length()-1) == '"'){ 
     arg.delete(arg.length()-1, arg.length()); 
     } 
     rev = arg.toString(); 
     break; 
    } 
    } 

} catch (Exception ex) { 
    getLog().error("Failed to obtain DOC REV!", ex); 
} 

return rev; 
} 

私はハードコーディングなどのためにappologise、私は学び、ここで実験しています。 「UUID」パラメータがのUUIDです)ターゲットドキュメント。 注ラッピングの除去「"」文字、我々はのEtagを得た(はい、のEtagヘッダはリビジョン番号です)

THEN、我々は実際に画像を送ることができる、ということだ:。

String serveURL = "http://192.168.56.101/testforms/" + data.getString(PARENT_UUID) + "/" + imgUuid; 

if (docRev != null && !docRev.trim().isEmpty()) { 
    //This is dumb... 
    serveURL += "?rev=" + docRev + "&_rev=" + docRev; 
} 
HttpPut post = new HttpPut(serveURL); 
    ByteArrayEntity entity = new ByteArrayEntity(imageData); 
entity.setContentType(data.getString(MIME_TYPE));; 

post.setEntity(entity); 

    HttpResponse formServResp = httpClient.execute(post); 
をこれにより

、私は自分のドキュメントに画像をアタッシェすることができた。前述のように

)、私もCouchDBのに新たなんだということに注意してくださいので、これを行うには、単純な方法があるかもしれません

してください!私がちょうど今発見した何か例えば、複数のクライアントが同時に同じ文書に画像を添付しようとする場合、競合状態の可能性があるということです。その理由は、rev値がドキュメントの変更ごとに変わるからです。 、あなたは

{"error":"conflict","reason":"Document update conflict."} 
のように、サーバからの応答を取得する最も簡単な解決策は、このような場合には をそれが動作するまで、ちょうどそのような場合に再試行することで、または自己課しエラー制限がヒットするまで...

乾杯!

+0

Apache HttpComponents 4.2.3 – demaniak

+1

を使用していたとしますか?if( "Etag" .equals(header.getName()))の代わりに 'if(" Etag ".equals (header.getName())){'。 (コメントは[another user](http://stackoverflow.com/users/5048961/cruxcon)の回答として投稿されました) –

関連する問題