Как поставить вложение изображения на CouchDB в Android? - PullRequest
1 голос
/ 24 марта 2012

Я использую HttpClient и mime, чтобы поместить файл изображения из клиента 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 Ответ

1 голос
/ 17 февраля 2013

УЖЕ, забудь, что я выложил здесь ранее. Это не так просто, как мы думали. Некоторые ссылки, которые я предлагаю вам прочитать:

  1. API CouchDB Document
  2. (черновик) Core API

Хорошо. Первое решение, если вы хотите «Автономный» или «встроенные вложения». В настоящее время я не знаю, что такое «за» и «против», НО, основываясь на вашем коде, и что я сделал, мы перейдем к «Автономному».

Во-первых, вам нужен номер версии (ревизии) документа, к которому вы хотите прикрепить свое изображение. Согласно приведенной выше ссылке, сделайте это, выполнив запрос 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;
}

Я прошу прощения за жесткое кодирование и т. Д., Я учусь и экспериментирую здесь;) Параметр «uuid» - это UUID целевого документа. Обратите внимание на удаление переносимых символов "" ", когда мы получили Etag (да, заголовок 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."}

Самое простое решение - просто повторить попытку в таком случае, пока оно не сработает, или пока не будет достигнут установленный лимит ошибок ...

Ура!

...