2012-03-24 2 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

좋아. 첫 번째 결정은 "독립 실행 형"또는 "인라인 첨부"를 원할 때입니다. 현재 나는 Pro와 Con의 코드가 무엇인지 모르지만 코드를 기반으로하고 있으며, 내가 한 일은 "독립형"으로 갈 것입니다.

먼저 이미지를 첨부 할 문서의 rev (개정) 번호가 필요합니다. 매개 변수는의 UUID는 "UUID") 을, 내가 배우고 여기에 실험을하고있어 나는 하드 코딩 등을 위해 appologise

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

: 위의 링크에 따라, 그 문서에 HEAD 요청을 수행하여이 작업을 수행 대상 문서. 참고 포장 ' "'의 제거 자 우리는 (예, Etag입니다 헤더 개정 번호입니다) THEN

Etag입니다을 받았을 때, 우리는 우리가 실제로 이미지를 보낼 수 있다는 왔을 때 :.

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

아파치 HttpComponents 4.2.3 – demaniak

+1

을 사용하고 있다고 언급해야할까요? if ("Etag".equals (header.getName())) 대신 {if ("Etag". equals (header.getName())) {'. ([다른 사용자] (http://stackoverflow.com/users/5048961/cruxcon)의 답변으로 게시 된 댓글) –

관련 문제