2012-03-24 7 views
1

Ich benutze HttpClient und Mime, um die Bilddatei vom Android-Client auf CouchDB zu legen. Aber es gibt einige Fehlermeldung wie dieseWie man Bildanhang an CouchDB in Android setzt?

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 

hier mein Code

ist
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(); 
    } 
} 

Bitte geben Sie mir eine Hand, Dank

Antwort

1

RECHTS, vergessen, was ich hier vorher geschrieben. Das ist nicht so einfach wie wir dachten. Einige Links, die ich Ihnen vorschlagen lesen:

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

Ok. Die erste Entscheidung ist, ob Sie "Standalone" oder "Inline-Anhänge" möchten. Derzeit weiß ich nicht, was die Pro's und Con's sind, ABER basierend auf Ihrem Code und was ich gemacht habe, werden wir uns für "Standalone" entscheiden.

Zuerst benötigen Sie die Rev (Revision) Nummer des Dokuments, an das Sie Ihr Bild anhängen möchten. Gemäß dem obigen Link, dies zu tun, indem Sie auf diesem doc eine HEAD-Anfrage zu tun:

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

ich für die Hardcoding etc neue ausprobieren, ich bin Lernen und Experimentieren hier;) Den „uuid“ Parameter sind die UUID das Zieldokument. Beachten Sie die Entfernung der Verpackung ‚"‘Zeichen, wenn wir haben die Etag (ja, der Etag-Header ist die Revisionsnummer)

dann, als wir haben das, können wir tatsächlich das Bild senden.

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

damit konnte ich Bilder meine docs zum einhängen;)

Wie bereits erwähnt, bitte beachten Sie, dass ich auf CouchDB auch bin neu, so dass es vielleicht einfache Möglichkeiten, dies zu tun

Etwas, das ich gerade entdeckt habe (aber hätte Earli sehen sollen) Es gibt hier das Potenzial einer Race Condition, wenn beispielsweise mehrere Clients versuchen, gleichzeitig Bilder an dasselbe Dokument anzuhängen. Der Grund dafür ist, dass sich der rev-Wert mit jeder Änderung des Dokuments ändert.

{"error":"conflict","reason":"Document update conflict."} 

einfachste Lösung In einem solchen Fall werden Sie

eine Antwort vom Server wie erhalten, ist nur in einem solchen Fall erneut zu versuchen, bis es funktioniert, oder bis eine selbst auferlegte Fehlergrenze getroffen wird ...

Prost!

+0

Sollte vielleicht nur erwähnen, ich war mit Apache HttpComponents 4.2.3 – demaniak

+1

Es sieht aus wie es sein sollte "if (" ETag ".equals (header.getName())) {' anstelle von 'if (" Etag ".equals (header.getName())) {'. (Kommentar als Antwort von [einem anderen Benutzer] (http://stackoverflow.com/users/5048961/cruxcon)) –

Verwandte Themen