ホームページ >Java >&#&チュートリアル >HttpEntity を使用せずに Volley でマルチパート POST リクエストを行う方法は?

HttpEntity を使用せずに Volley でマルチパート POST リクエストを行う方法は?

Linda Hamilton
Linda Hamiltonオリジナル
2024-12-03 04:29:14631ブラウズ

How to Make Multipart POST Requests with Volley Without Using HttpEntity?

HttpEntity を使用せずに Volley でマルチパート POST リクエストを実行する方法

Volley は、HTTP リクエストを作成するための人気のある Android ライブラリです。以前の API バージョンでは、HttpEntity はマルチパート フォーム データの送信に Volley と組み合わせて使用​​されていました。ただし、API 22 で HttpEntity が非推奨となり、API 23 で完全に削除されたため、開発者には課題が残されています。

この記事では、 HttpEntity.提供されたコードを使用すると、テキスト データとともに複数のファイルをアップロードできます。

コードの概要

ここで説明する実装は、MultipartActivity と MultipartRequest の 2 つのクラスで構成されます。 MultipartActivity はマルチパート フォーム データの準備を処理しますが、MultipartRequest は Volley の Request クラスを拡張し、マルチパート ボディの処理とサーバー応答の処理に必要なメソッドをオーバーライドします。

使用法

このソリューションを利用するには、次の手順に従います。 :

  1. URL、mimeType、multipart を指定して MultipartRequest のインスタンスを作成します。本文と応答リスナー。
  2. getParams() を使用して追加のテキスト パラメーターを追加します。
  3. 関連するファイルまたはデータを含む DataPart オブジェクトを生成し、それらを getByteData() メソッドに追加します。
  4. 次を使用して、MultipartRequest を Volley のリクエスト キューに追加します。 addToRequestQueue().

コード例

MultipartActivity.java:

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.Toast;

import com.android.volley.NetworkResponse;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.example.multipartvolley.MultipartRequest;
import com.example.multipartvolley.VolleySingleton;

import java.util.HashMap;
import java.util.Map;

public class MultipartActivity extends Activity {

    private Context context = this;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Assuming you have prepared file data in fileData1 and fileData2
        String url = "http://192.168.1.100/api/postfile";
        MultipartRequest multipartRequest = new MultipartRequest(url, null, "multipart/form-data", multipartBody, new Response.Listener<NetworkResponse>() {
            @Override
            public void onResponse(NetworkResponse response) {
                Toast.makeText(context, "Upload successfully!", Toast.LENGTH_SHORT).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(context, "Upload failed!\r\n" + error.toString(), Toast.LENGTH_SHORT).show();
            }
        }) {
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<>();
                params.put("text_field1", "Value for text field 1");
                params.put("text_field2", "Value for text field 2");
                return params;
            }

            @Override
            protected Map<String, DataPart> getByteData() {
                Map<String, DataPart> params = new HashMap<>();
                params.put("file_name1", new DataPart("file_name1.txt", "file content 1".getBytes(), "text/plain"));
                params.put("file_name2", new DataPart("file_name2.png", fileData1, "image/png"));
                return params;
            }
        };

        VolleySingleton.getInstance(context).addToRequestQueue(multipartRequest);
    }
}

MultipartRequest.java:

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HttpHeaderParser;

import java.util.HashMap;
import java.util.Map;

class MultipartRequest extends Request<NetworkResponse> {

    private final Response.Listener<NetworkResponse> mListener;
    private final Response.ErrorListener mErrorListener;
    private Map<String, String> mHeaders;
    private Map<String, DataPart> mByteData;

    MultipartRequest(String url,
                     Map<String, String> headers,
                     String contentType,
                     Map<String, DataPart> byteData,
                     Response.Listener<NetworkResponse> listener,
                     Response.ErrorListener errorListener) {
        super(Method.POST, url, errorListener);
        this.mListener = listener;
        this.mErrorListener = errorListener;
        this.mHeaders = headers;
        this.mByteData = byteData;
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        return mHeaders != null ? mHeaders : super.getHeaders();
    }

    @Override
    public String getBodyContentType() {
        return "multipart/form-data; boundary=" + getBoundary();
    }

    @Override
    public byte[] getBody() throws AuthFailureError {
        return encodeMultipartData(mByteData, getBoundary());
    }

    private String getBoundary() {
        return Long.toHexString(System.currentTimeMillis());
    }

    @Override
    protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
        try {
            return Response.success(
                    response,
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (Exception e) {
            return Response.error(new ParseError(e));
        }
    }

    @Override
    protected void deliverResponse(NetworkResponse response) {
        mListener.onResponse(response);
    }

    @Override
    public void deliverError(VolleyError error) {
        mErrorListener.onErrorResponse(error);
    }

    protected static byte[] encodeMultipartData(Map<String, DataPart> dataParts,
                                                String boundary) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(bos);

        try {
            for (Map.Entry<String, DataPart> entry : dataParts.entrySet()) {
                dos.writeBytes(twoHyphens + boundary + lineEnd);
                dos.writeBytes("Content-Disposition: form-data; name=\"" +
                        entry.getKey() + "\"" +
                        "; filename=\"" +
                        entry.getValue().getFileName() + "\"" +
                        lineEnd);
                dos.writeBytes(String.format("Content-Type: %s%s", entry.getValue().getType(), lineEnd));
                dos.writeBytes(lineEnd);

                dos.write(entry.getValue().getContent());
                dos.writeBytes(lineEnd);
            }
            dos.writeBytes(lineEnd);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    class DataPart {
        private String fileName;
        private byte[] content;
        private String type;

        DataPart(String fileName, byte[] content, String type) {
            this.fileName = fileName;
            this.content = content;
            this.type = type;
        }

        String getFileName() {
            return fileName;
        }

        byte[] getContent() {
            return content;
        }

        String getType() {
            return type;
        }
    }
}

このコードは次の処理を行いますファイルとテキストの両方のパラメーターをサーバーに安全に渡すことができるマルチパート フォーム データ リクエスト。最終的なコードは本番環境で使用するものではないため、特定の要件に応じて変更する必要があることに注意することが重要です。

以上がHttpEntity を使用せずに Volley でマルチパート POST リクエストを行う方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。