Senden von Bildern mit Http Post

129

Ich möchte ein Bild vom Android-Client mit Http Post an den Django-Server senden. Das Bild wird aus der Galerie ausgewählt. Derzeit verwende ich Listenwertnamenpaare, um die erforderlichen Daten an den Server zu senden und Antworten von Django in JSON zu empfangen. Kann der gleiche Ansatz für Bilder verwendet werden (mit URLs für Bilder, die in JSON-Antworten eingebettet sind)?

Was ist auch eine bessere Methode: Fernzugriff auf Bilder, ohne sie vom Server herunterzuladen oder in einem Bitmap-Array herunterzuladen, zu speichern und lokal zu verwenden? Die Bilder sind wenige (<10) und klein (50 * 50 Dip).

Jedes Tutorial zur Lösung dieser Probleme wäre sehr dankbar.

Bearbeiten: Die aus der Galerie ausgewählten Bilder werden an den Server gesendet, nachdem sie auf die erforderliche Größe skaliert wurden.

Ursprünglicher Pappachan
quelle

Antworten:

144

Ich gehe davon aus, dass Sie den Pfad und den Dateinamen des Bildes kennen, das Sie hochladen möchten. Fügen Sie diese Zeichenfolge zu Ihrer NameValuePairVerwendung imageals Schlüsselname hinzu.

Das Senden von Bildern kann mithilfe der HttpComponents-Bibliotheken erfolgen . Laden Sie die aktuelle Httpclient (derzeit 4.0.1 ) binär mit Abhängigkeiten Paket und kopieren apache-mime4j-0.6.jarund httpmime-4.0.1.jarin Ihr Projekt und fügen Sie sie in Ihre Java - Build - Pfad.

Sie müssen Ihrer Klasse die folgenden Importe hinzufügen.

import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;

Jetzt können Sie ein erstellen MultipartEntity, um ein Bild an Ihre POST-Anfrage anzuhängen. Der folgende Code zeigt ein Beispiel dafür:

public void post(String url, List<NameValuePair> nameValuePairs) {
    HttpClient httpClient = new DefaultHttpClient();
    HttpContext localContext = new BasicHttpContext();
    HttpPost httpPost = new HttpPost(url);

    try {
        MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

        for(int index=0; index < nameValuePairs.size(); index++) {
            if(nameValuePairs.get(index).getName().equalsIgnoreCase("image")) {
                // If the key equals to "image", we use FileBody to transfer the data
                entity.addPart(nameValuePairs.get(index).getName(), new FileBody(new File (nameValuePairs.get(index).getValue())));
            } else {
                // Normal string data
                entity.addPart(nameValuePairs.get(index).getName(), new StringBody(nameValuePairs.get(index).getValue()));
            }
        }

        httpPost.setEntity(entity);

        HttpResponse response = httpClient.execute(httpPost, localContext);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Ich hoffe das hilft dir ein bisschen in die richtige Richtung.

Piro
quelle
6
Ich würde es auf jeden Fall empfehlen. Auf diese Weise können Sie wahrscheinlich Django-Funktionen verwenden, um das Bild zu empfangen und einfach zu speichern. Eine andere Möglichkeit wäre, den Bytestream vom Image in eine Base64-codierte Zeichenfolge zu codieren und serverseitig zu decodieren. Aber das wäre meiner Meinung nach zu mühsam und nicht der richtige Weg.
Piro
6
Hey Leute, gibt es eine Möglichkeit, dies ohne MultipartEntity zu tun? Ich möchte WIRKLICH nicht alle Apache HC nur für diese 4 Klassen importieren. :-(
Neil Traft
6
Fügen Sie einfach einen zweiten Parameter FileBodymit Ihrem gewünschten Mime-Typ hinzu. ZB:new FileBody(new File (nameValuePairs.get(index).getValue()), "image/jpeg")
Piro
4
Es sieht so aus, als wäre Multipartentität veraltet?
Nanne
1
@Piro Ich habe darüber nachgedacht, auch deine Antwort zu bearbeiten. Eine mehrteilige Entität wird zusammen mit der von Ihnen verwendeten String-Body-Version abgeschrieben. Der Grund, warum ich nicht bearbeite, ist, dass ich nicht alle Daten in Namenswertpaaren binden konnte, wie Sie es getan haben.
Illegales Argument
15

Version 4.3.5 Code aktualisiert

  • httpclient-4.3.5.jar
  • httpcore-4.3.2.jar
  • httpmime-4.3.5.jar

Da MultipartEntitywurde veraltet . Bitte beachten Sie den Code unten.

String responseBody = "failure";
HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

String url = WWPApi.URL_USERS;
Map<String, String> map = new HashMap<String, String>();
map.put("user_id", String.valueOf(userId));
map.put("action", "update");
url = addQueryParams(map, url);

HttpPost post = new HttpPost(url);
post.addHeader("Accept", "application/json");

MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setCharset(MIME.UTF8_CHARSET);

if (career != null)
    builder.addTextBody("career", career, ContentType.create("text/plain", MIME.UTF8_CHARSET));
if (gender != null)
    builder.addTextBody("gender", gender, ContentType.create("text/plain", MIME.UTF8_CHARSET));
if (username != null)
    builder.addTextBody("username", username, ContentType.create("text/plain", MIME.UTF8_CHARSET));
if (email != null)
    builder.addTextBody("email", email, ContentType.create("text/plain", MIME.UTF8_CHARSET));
if (password != null)
    builder.addTextBody("password", password, ContentType.create("text/plain", MIME.UTF8_CHARSET));
if (country != null)
    builder.addTextBody("country", country, ContentType.create("text/plain", MIME.UTF8_CHARSET));
if (file != null)
    builder.addBinaryBody("Filedata", file, ContentType.MULTIPART_FORM_DATA, file.getName());

post.setEntity(builder.build());

try {
    responseBody = EntityUtils.toString(client.execute(post).getEntity(), "UTF-8");
//  System.out.println("Response from Server ==> " + responseBody);

    JSONObject object = new JSONObject(responseBody);
    Boolean success = object.optBoolean("success");
    String message = object.optString("error");

    if (!success) {
        responseBody = message;
    } else {
        responseBody = "success";
    }

} catch (Exception e) {
    e.printStackTrace();
} finally {
    client.getConnectionManager().shutdown();
}
AZ_
quelle
Welche Glaspakete werden benötigt?
3
httpclient-4.3.5.jar httpcore-4.3.2.jar httpmime-4.3.5.jar
AZ_
Was gibt addQueryParams zurück?
San
11

Die loopj- Bibliothek kann für diesen Zweck direkt verwendet werden:

SyncHttpClient client = new SyncHttpClient();
RequestParams params = new RequestParams();
params.put("text", "some string");
params.put("image", new File(imagePath));

client.post("http://example.com", params, new TextHttpResponseHandler() {
  @Override
  public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
    // error handling
  }

  @Override
  public void onSuccess(int statusCode, Header[] headers, String responseString) {
    // success
  }
});

http://loopj.com/

vonox7
quelle
5

Ich hatte große Probleme beim Implementieren der Veröffentlichung eines Images vom Android-Client zum Servlet mithilfe von httpclient-4.3.5.jar, httpcore-4.3.2.jar, httpmime-4.3.5.jar. Ich habe immer einen Laufzeitfehler bekommen. Ich habe herausgefunden, dass Sie diese Gläser grundsätzlich nicht mit Android verwenden können, da Google eine ältere Version von HttpClient in Android verwendet. Die Erklärung finden Sie hier http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html . Sie müssen das Glas httpclientandroidlib-1.2.1 aus der http-Client-Bibliothek von Android herunterladen . Ändern Sie dann Ihre Importe von or.apache.http.client in ch.boye.httpclientandroidlib. Hoffe das hilft.

DavidC
quelle
-13

Normalerweise mache ich das in dem Thread, der die JSON-Antwort verarbeitet:

try {
  Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageUrl).getContent());
} catch (MalformedURLException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
}

Wenn Sie Transformationen für das Bild durchführen müssen, möchten Sie anstelle einer Bitmap ein Drawable erstellen.

Dylan McClung
quelle
3
Die Frage ist, wie man ein Bild postet und nicht wie man es bekommt.
Dwbrito