ホームページ >Java >&#&チュートリアル >Android で Volley を使用して機能する POST マルチパート リクエストを作成する方法?

Android で Volley を使用して機能する POST マルチパート リクエストを作成する方法?

Linda Hamilton
Linda Hamiltonオリジナル
2024-12-01 05:45:10334ブラウズ

How to Make Working POST Multipart Requests with Volley in Android?

最新の API を使用した Volley による POST マルチパート リクエストの作業

Android 開発では、ファイルやテキスト データのアップロードなどのマルチパート リクエストを送信します。共通のタスク。 HttpEntity は新しい API バージョンでは使用できなくなりましたが、Volley を使用してマルチパート リクエストを実現する方法はまだあります。

基本的なマルチパート リクエストの作成

マルチパート リクエストを作成するには、Volley の Request クラスを次のように拡張できます。したがって:

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.Map;

class MultipartRequest extends Request<NetworkResponse> {
    // Listener for request response
    private final Response.Listener<NetworkResponse> mListener;
    // Listener for request error
    private final Response.ErrorListener mErrorListener;
    // Request headers
    private final Map<String, String> mHeaders;
    // Multipart mime type (e.g., "multipart/form-data; boundary=XXX")
    private final String mMimeType;
    // Request body as multipart
    private final byte[] mMultipartBody;

    // Constructor
    public MultipartRequest(String url, Map<String, String> headers, String mimeType, byte[] multipartBody,
                            Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
        super(Method.POST, url, errorListener);
        this.mListener = listener;
        this.mErrorListener = errorListener;
        this.mHeaders = headers;
        this.mMimeType = mimeType;
        this.mMultipartBody = multipartBody;
    }

    // Getters and setters

    // Override getHeaders() if you need to add custom headers
    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        return (mHeaders != null) ? mHeaders : super.getHeaders();
    }

    // Override getBodyContentType() to set the correct mime type for the multipart request
    @Override
    public String getBodyContentType() {
        return mMimeType;
    }

    // Override getBody() to return the multipart body
    @Override
    public byte[] getBody() throws AuthFailureError {
        return mMultipartBody;
    }

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

    // Delivering response and error
    @Override
    protected void deliverResponse(NetworkResponse response) {
        mListener.onResponse(response);
    }

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

マルチパート ボディの構築

マルチパート ボディを構築するには、次の手順を使用できます:

byte[] multipartBody = new byte[0];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
try {
    // Text data
    buildTextPart(dos, "name", "John Doe");
    buildTextPart(dos, "email", "john.doe@email.com");

    // Image data
    Bitmap imageBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.my_image);
    buildImagePart(dos, "image", imageBitmap);

} catch (IOException e) {
    e.printStackTrace();
}
multipartBody = bos.toByteArray();

リクエストにマルチパート ボディを含めます

マルチパートボディが構築されたら、次のように MultipartRequest インスタンスに含めることができます。

MultipartRequest request = new MultipartRequest(
        "my_url",
        null, // Headers
        "multipart/form-data",
        multipartBody,
        new Response.Listener<NetworkResponse>() {
            @Override
            public void onResponse(NetworkResponse response) {
                // Handle response
            }
        },
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // Handle error
            }
        });

リクエストにテキスト データを追加

画像データに加えて、リクエストにテキスト データを含めることもできます:

private void buildTextPart(DataOutputStream dataOutputStream, String name, String value) throws IOException {
    dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
    dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"" + lineEnd);
    dataOutputStream.writeBytes(lineEnd);
    dataOutputStream.writeBytes(value);
    dataOutputStream.writeBytes(lineEnd);
}

2 つのハイフン、境界線、および lineEnd を適切なものに置き換えます。コードからの値。

完全なコード サンプル

次のコード サンプルは、VolleyMultipartRequest クラスの完全なモジュール実装を示しています。

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.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class VolleyMultipartRequest extends Request<NetworkResponse> {
    private final Response.Listener<NetworkResponse> mListener;
    private final Response.ErrorListener mErrorListener;
    private final Map<String, String> mHeaders;
    private final String mMimeType;
    private final byte[] mMultipartBody;

    public VolleyMultipartRequest(int method, String url, Response.Listener<NetworkResponse> listener,
                                  Response.ErrorListener errorListener) {
        super(method, url, errorListener);
        this.mListener = listener;
        this.mErrorListener = errorListener;
        this.mHeaders = null;
        this.mMimeType = null;
        this.mMultipartBody = null;
    }

    public VolleyMultipartRequest(String url, Map<String, String> headers, String mimeType, byte[] multipartBody,
                                  Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
        super(Method.POST, url, errorListener);
        this.mListener = listener;
        this.mErrorListener = errorListener;
        this.mHeaders = headers;
        this.mMimeType = mimeType;
        this.mMultipartBody = multipartBody;
    }

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

    @Override
    public String getBodyContentType() {
        return mMimeType;
    }

    @Override
    public byte[] getBody() throws AuthFailureError {
        return mMultipartBody;
    }

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

    public static Map<String, DataPart> createMultipartRequestParts(Map<String, String> params, Map<String, DataPart> data) {
        Map<String, DataPart> multipartParams = new HashMap<>();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            multipartParams.put(entry.getKey(), new DataPart(entry.getValue()));
        }
        for (Map.Entry<String, DataPart> entry : data.entrySet()) {
            multipartParams.put(entry.getKey(), entry.getValue());
        }
        return multipartParams;
    }

    public static byte[] createMultipartBody(Map<String, DataPart> data, String boundary) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(bos);
        for (Map.Entry<String, DataPart> entry : data.entrySet()) {
            buildTextPart(dos, entry.getKey(), entry.getValue().getContentType(), entry.getValue().getFileName(), entry.getValue().getData());
        }

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

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