Mengirim gambar menggunakan Http Post


129

Saya ingin mengirim gambar dari klien android ke server Django menggunakan Http Post. Gambar dipilih dari galeri. Saat ini, saya menggunakan daftar nama nilai Pasangan untuk mengirim data yang diperlukan ke server dan menerima tanggapan dari Django di JSON. Bisakah pendekatan yang sama digunakan untuk gambar (dengan url untuk gambar yang tertanam dalam respons JSON)?

Juga, yang merupakan metode yang lebih baik: mengakses gambar dari jarak jauh tanpa mengunduhnya dari server atau mengunduh dan menyimpannya dalam array Bitmap dan menggunakannya secara lokal? Gambar sedikit jumlahnya (<10) dan ukurannya kecil (50 * 50 celup).

Setiap tutorial untuk mengatasi masalah ini akan sangat dihargai.

Sunting: Gambar yang dipilih dari galeri dikirim ke server setelah diubah ke ukuran yang diperlukan.

Jawaban:


144

Saya akan berasumsi bahwa Anda tahu jalur dan nama file dari gambar yang ingin Anda unggah. Tambahkan string ini ke NameValuePairpenggunaan Anda imagesebagai nama kunci.

Mengirim gambar dapat dilakukan menggunakan pustaka HttpComponents . Unduh biner HttpClient terbaru (saat ini 4.0.1 ) dengan paket dependensi dan salin apache-mime4j-0.6.jardan httpmime-4.0.1.jarke proyek Anda dan tambahkan mereka ke path Java build Anda.

Anda perlu menambahkan impor berikut ke kelas Anda.

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;

Sekarang Anda dapat membuat MultipartEntityuntuk melampirkan gambar ke permintaan POST Anda. Kode berikut menunjukkan contoh bagaimana melakukan ini:

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

Saya harap ini sedikit membantu Anda ke arah yang benar.


6
Saya pasti akan merekomendasikan ini. Dengan cara ini Anda mungkin dapat menggunakan fitur Django untuk menerima gambar dan menyimpannya dengan mudah. Salah satu cara lain adalah dengan meng-encode aliran byte dari gambar ke string yang disandikan base64 dan mendekode sisi server. Tapi ini akan terlalu merepotkan menurut saya dan bukan jalan yang harus ditempuh.
Piro

6
Hai teman-teman, apakah ada cara untuk melakukan ini tanpa MultipartEntity? SAYA BENAR-BENAR tidak ingin mengimpor semua Apache HC hanya untuk 4 kelas tersebut. :-(
Neil Traft

6
Cukup tambahkan parameter ke FileBody- 2 dengan Tipe Mime yang Anda inginkan. Misalnya:new FileBody(new File (nameValuePairs.get(index).getValue()), "image/jpeg")
Piro

4
Sepertinya multipartentitas sudah usang?
Nanne

1
@Piro Saya juga berpikir tentang mengedit jawaban Anda. Entitas multi bagian didepresiasi bersama dengan versi string body yang Anda gunakan. Alasan saya tidak mengedit adalah karena saya tidak dapat mengikat semua data dalam perbaikan nilai nama seperti yang telah Anda lakukan.
Argumen Ilegal

15

Versi 4.3.5 Kode Diperbarui

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

Sejak MultipartEntitytelah ditinggalkan . Silakan lihat kode di bawah ini.

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

Paket jar mana yang dibutuhkan?

3
httpclient-4.3.5.jar httpcore-4.3.2.jar httpmime-4.3.5.jar
AZ_

Apa yang dikembalikan addQueryParams?
San

11

The loopj perpustakaan dapat digunakan lurus ke depan untuk tujuan ini:

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/


5

Saya banyak berjuang untuk mengimplementasikan pengiriman gambar dari klien Android ke servlet menggunakan httpclient-4.3.5.jar, httpcore-4.3.2.jar, httpmime-4.3.5.jar. Saya selalu mendapat kesalahan runtime. Saya menemukan bahwa pada dasarnya Anda tidak dapat menggunakan toples ini dengan Android karena Google menggunakan versi HttpClient yang lebih lama di Android. Penjelasannya di sini http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html . Anda perlu mendapatkan toples httpclientandroidlib-1.2.1 dari pustaka http-client android . Kemudian ubah impor Anda dari or.apache.http.client ke ch.boye.httpclientandroidlib. Semoga ini membantu.


-13

Saya biasanya melakukan ini di utas yang menangani respons json:

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

Jika Anda perlu melakukan transformasi pada gambar, Anda ingin membuat Drawable alih-alih Bitmap.


3
Pertanyaannya adalah bagaimana cara memposting gambar, dan bukan bagaimana cara mendapatkannya.
dwbrito
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.