Maison > Java > javaDidacticiel > Comment créer des requêtes POST multipart fonctionnelles avec Volley sous Android ?

Comment créer des requêtes POST multipart fonctionnelles avec Volley sous Android ?

Linda Hamilton
Libérer: 2024-12-01 05:45:10
original
405 Les gens l'ont consulté

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

Travailler une requête POST multipart avec Volley à l'aide de la dernière API

Dans le développement Android, l'envoi de requêtes multipart, telles que le téléchargement de fichiers et de données texte, est une tâche commune. Bien que HttpEntity ne soit plus disponible dans les versions d'API les plus récentes, il existe toujours des moyens de réaliser des requêtes multiparts à l'aide de Volley.

Création d'une requête multipart de base

Pour créer une requête multipart de base , nous pouvons étendre la classe Volley's Request comme ceci :

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);
    }
}
Copier après la connexion

Construire le Multipart Corps

Pour construire le corps en plusieurs parties, nous pouvons utiliser les étapes suivantes :

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();
Copier après la connexion

Inclure le corps en plusieurs parties dans la requête

Une fois le corps en plusieurs parties construit, nous pouvons l'inclure dans notre instance MultipartRequest comme donc :

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
            }
        });
Copier après la connexion

Ajout de données texte à la demande

En plus des données d'image, vous pouvez également inclure des données texte dans votre demande :

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);
}
Copier après la connexion

Remplacez twoHyphens, border et lineEnd par les valeurs appropriées de votre code.

Code complet Exemple

L'exemple de code suivant montre une implémentation modulaire complète d'une classe 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());
        }
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal