Http Postを使用して画像を送信する


129

Http Postを使用して、AndroidクライアントからDjangoサーバーに画像を送信したいと思います。画像はギャラリーから選択されます。現在、リスト値名Pairsを使用して必要なデータをサーバーに送信し、Djangoからの応答をJSONで受信しています。同じアプローチを画像に使用できますか(画像のURLはJSON応答に埋め込まれています)?

また、どちらがより良い方法であるか:サーバーからダウンロードせずにリモートで画像にアクセスするか、ビットマップ配列にダウンロードして保存してローカルで使用するか?画像は数が少なく(<10)、サイズが小さい(50 * 50 dip)。

これらの問題に取り組むためのチュートリアルがあれば、大歓迎です。

編集:ギャラリーから選択された画像は、必要なサイズにスケーリングされた後、サーバーに送信されます。

回答:


144

アップロードしたい画像のパスとファイル名がわかっていると仮定します。キー名としてNameValuePairを使用しimageて、この文字列を追加します。

画像の送信は、HttpComponentsライブラリを使用して行うことができます。最新のHttpClientを(現在はダウンロード4.0.1依存関係のパッケージやコピーで)バイナリをapache-mime4j-0.6.jarしてhttpmime-4.0.1.jar、あなたのプロジェクトにして、Javaのビルド・パスに追加します。

次のインポートをクラスに追加する必要があります。

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;

これでMultipartEntity、POSTリクエストに画像を添付するを作成できます。次のコードは、これを行う方法の例を示しています。

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

これがあなたの正しい方向性に少し役立つことを願っています。


6
私は間違いなくこれをお勧めします。この方法では、おそらくDjangoの機能を使用して画像を受信し、簡単に保存できます。もう1つの方法は、画像からのバイトストリームをbase64エンコードされた文字列にエンコードし、サーバー側でデコードすることです。しかし、これは私の意見ではあまり面倒であり、進むべき道ではありません。
ピロ

6
皆さん、MultipartEntityなしでこれを行う方法はありますか?これらの4つのクラスだけのために、Apache HCをすべてインポートしたくありません。:-(
Neil Traft、2010

6
FileBody目的のMIMEタイプで2番目のパラメータを追加するだけです。例:new FileBody(new File (nameValuePairs.get(index).getValue()), "image/jpeg")
ピロ

4
multipartentityは廃止されたようです。
ナンヌ2014年

1
@Piro私もあなたの答えを編集することを考えていました。マルチパートエンティティは、使用している文字列の本体バージョンとともに減価償却されます。編集していない理由は、名前と値のペアのすべてのデータをバインドできなかったためです。
違法な議論

15

バージョン4.3.5更新されたコード

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

廃止MultipartEntityれて以来。以下のコードをご覧ください。

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

どのjarパッケージが必要ですか?

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

addQueryParamsは何を返しますか?
サン

11

loopjのライブラリーは、この目的のためにまっすぐフォワード使用することができます。

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

私は、httpclient-4.3.5.jar、httpcore-4.3.2.jar、httpmime-4.3.5.jarを使用してAndroidクライアントからサーブレットに画像をポストすることを実装しようとして多くの苦労しました。常に実行時エラーが発生しました。GoogleがAndroidで古いバージョンのHttpClientを使用しているため、基本的にこれらのjarをAndroidで使用できないことがわかりました。説明はこちらhttp://hc.apache.org/httpcomponents-client-4.3.x/android-port.htmlです。android http-client libraryからhttpclientandroidlib-1.2.1 jarを取得する必要があります。次に、インポートをor.apache.http.clientからch.boye.httpclientandroidlibに変更します。お役に立てれば。


-13

私は通常、json応答を処理するスレッドでこれを行います。

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

画像を変換する必要がある場合は、ビットマップではなくドローアブルを作成する必要があります。


3
問題は、画像を投稿する方法であり、取得する方法ではありません。
dwbrito 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.