Đăng yêu cầu nhiều phần với Android SDK


79

Tôi đang cố gắng làm một việc mà tôi nghĩ sẽ tương đối đơn giản: Tải hình ảnh lên máy chủ có Android SDK. Tôi đã tìm thấy rất nhiều mã ví dụ:

http://groups.google.com/group/android-developers/browse_thread/thread/f9e17bbaf50c5fc/46145fcacd450e48

http://linklens.blogspot.com/2009/06/android-multipart-upload.html

Nhưng không có tác dụng với tôi. Sự nhầm lẫn mà tôi tiếp tục gặp phải là những gì thực sự cần thiết để thực hiện một yêu cầu nhiều phần. Là gì đơn giản nhất cách để có một tải lên nhiều phần dữ liệu (với một hình ảnh) dành cho Android?

Bất kỳ giúp đỡ hoặc tư vấn sẽ được đánh giá rất nhiều!


Vấn đề bạn đang gặp phải với các phương pháp bạn đã thử cho đến nay là gì?
Christopher Orr

1
Ôi rất nhiều vấn đề. Hiện tại, việc lấy lại tiểu ảnh từ bộ chọn ảnh vào một tệp mà tôi có thể đính kèm vào MultipartEntity. Nhưng tôi thậm chí không chắc đây là cách chính xác để tạo một yêu cầu đa cổng.
jpoz

Câu trả lời:


103

Cập nhật ngày 29 tháng 4 năm 2014:

Câu trả lời của tôi bây giờ hơi cũ và tôi đoán bạn muốn sử dụng một số loại thư viện cấp cao như Retrofit .


Dựa trên blog này, tôi đã đưa ra giải pháp sau: http://blog.tacticalnuclearstrike.com/2010/01/using-multipartentity-in-android-appices/

Bạn sẽ phải tải xuống các thư viện bổ sung để MultipartEntitychạy!

1) Tải xuống httpcomponents-client-4.1.zip từ http://james.apache.org/download.cgi#Apache_Mime4J và thêm apache-mime4j-0.6.1.jar vào dự án của bạn.

2) Tải xuống httpcomponents-client-4.1-bin.zip từ http://hc.apache.org/downloads.cgi và thêm httpclient-4.1.jar, httpcore-4.1.jar và httpmime-4.1.jar vào dự án của bạn.

3) Sử dụng mã ví dụ bên dưới.

private DefaultHttpClient mHttpClient;


public ServerCommunication() {
    HttpParams params = new BasicHttpParams();
    params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
    mHttpClient = new DefaultHttpClient(params);
}


public void uploadUserPhoto(File image) {

    try {

        HttpPost httppost = new HttpPost("some url");

        MultipartEntity multipartEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);  
        multipartEntity.addPart("Title", new StringBody("Title"));
        multipartEntity.addPart("Nick", new StringBody("Nick"));
        multipartEntity.addPart("Email", new StringBody("Email"));
        multipartEntity.addPart("Description", new StringBody(Settings.SHARE.TEXT));
        multipartEntity.addPart("Image", new FileBody(image));
        httppost.setEntity(multipartEntity);

        mHttpClient.execute(httppost, new PhotoUploadResponseHandler());

    } catch (Exception e) {
        Log.e(ServerCommunication.class.getName(), e.getLocalizedMessage(), e);
    }
}

private class PhotoUploadResponseHandler implements ResponseHandler<Object> {

    @Override
    public Object handleResponse(HttpResponse response)
            throws ClientProtocolException, IOException {

        HttpEntity r_entity = response.getEntity();
        String responseString = EntityUtils.toString(r_entity);
        Log.d("UPLOAD", responseString);

        return null;
    }

}

4
Tôi không thể tìm thấy thư viện MultipartEntity cũng như HttpMultipartClient trong Android. Bạn có thể vui lòng giúp tôi không?
Nguyễn Minh Bình

23
Đây là câu trả lời chính xác. thật tiếc khi lớp này không có trong Android SDK.
mooncheese

2
Tại sao bạn cần apache-mime4j-0.6.1.jar?
JPM

5
bất kỳ ai đang tìm kiếm bộ tệp đầu tiên này hiện đang ở đây: psg.mtu.edu/pub/apache//james/mime4j
Keeano

5
Cảm ơn vì giải pháp. Tuy nhiên, MultipartEntityhiện không được dùng nữa. Bài này có thể hướng dẫn những ai muốn sử dụng MultipartEntityBuilderthay vì: stackoverflow.com/a/19188010/1276636
Sufian

47

Như MultiPartEntitybị phản đối . Vì vậy, đây là cách mới để làm điều đó! Và bạn chỉ cần httpcore.jar(latest)httpmime.jar(latest)tải chúng xuống từ trang Apache.

try
{
    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost(URL);

    MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
    entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

    entityBuilder.addTextBody(USER_ID, userId);
    entityBuilder.addTextBody(NAME, name);
    entityBuilder.addTextBody(TYPE, type);
    entityBuilder.addTextBody(COMMENT, comment);
    entityBuilder.addTextBody(LATITUDE, String.valueOf(User.Latitude));
    entityBuilder.addTextBody(LONGITUDE, String.valueOf(User.Longitude));

    if(file != null)
    {
        entityBuilder.addBinaryBody(IMAGE, file);
    }

    HttpEntity entity = entityBuilder.build();
    post.setEntity(entity);
    HttpResponse response = client.execute(post);
    HttpEntity httpEntity = response.getEntity();
    result = EntityUtils.toString(httpEntity);
    Log.v("result", result);
}
catch(Exception e)
{
    e.printStackTrace();
}

1
+1 để sử dụng Trình tạo, vì tính năng thuyết minh trực tiếp không được dùng nữa.
npace

Câu trả lời này đã tiết kiệm cho tôi rất nhiều thời gian. Cảm ơn!
PearsonArtPhoto

@muhammad babar, bạn có thể cho tôi biết làm thế nào nếu tôi muốn tải lên nhiều Hình ảnh bằng cách sử dụng MultipartEntityBuilder?
Menma

bên trong một vòng lặp và sau đó entityBuilder.addBinaryBody(key, file);đảm bảo rằng khóa là duy nhất.
Muhammad Babar

16
sử dụng biên dịch 'org.apache.httpcomponents: httpmime: 4.3.4' biên dịch 'org.apache.httpcomponents: httpcore: 4.3.2' cho các phụ thuộc studio android
Tyler Davis

15

Đây là giải pháp LIGHT WEIGHTED phù hợp với tôi mà không có HTTPCore bên ngoài và các lib như vậy. Tôi đang gặp phải vấn đề về phương thức 64K nên không còn tùy chọn nào để tránh các thư viện HTTPCore

import java.util.List;

import java.io.BufferedReader;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

/**
 * This utility class provides an abstraction layer for sending multipart HTTP
 * POST requests to a web server.
 *
 * @author www.codejava.net
 */
public class MultipartUtility {
    private final String boundary;
    private static final String LINE_FEED = "\r\n";
    private HttpURLConnection httpConn;
    private String charset;
    private OutputStream outputStream;
    private PrintWriter writer;

    /**
     * This constructor initializes a new HTTP POST request with content type
     * is set to multipart/form-data
     *
     * @param requestURL
     * @param charset
     * @throws IOException
     */
    public MultipartUtility(String requestURL, String charset)
            throws IOException {
        this.charset = charset;

        // creates a unique boundary based on time stamp
        boundary = "===" + System.currentTimeMillis() + "===";

        URL url = new URL(requestURL);
        httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setUseCaches(false);
        httpConn.setDoOutput(true); // indicates POST method
        httpConn.setDoInput(true);
        httpConn.setRequestProperty("Content-Type",
                "multipart/form-data; boundary=" + boundary);
        httpConn.setRequestProperty("User-Agent", "CodeJava Agent");
        httpConn.setRequestProperty("Test", "Bonjour");
        outputStream = httpConn.getOutputStream();
        writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
                true);
    }

    /**
     * Adds a form field to the request
     *
     * @param name  field name
     * @param value field value
     */
    public void addFormField(String name, String value) {
        writer.append("--" + boundary).append(LINE_FEED);
        writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
                .append(LINE_FEED);
        writer.append("Content-Type: text/plain; charset=" + charset).append(
                LINE_FEED);
        writer.append(LINE_FEED);
        writer.append(value).append(LINE_FEED);
        writer.flush();
    }

    /**
     * Adds a upload file section to the request
     *
     * @param fieldName  name attribute in <input type="file" name="..." />
     * @param uploadFile a File to be uploaded
     * @throws IOException
     */
    public void addFilePart(String fieldName, File uploadFile)
            throws IOException {
        String fileName = uploadFile.getName();
        writer.append("--" + boundary).append(LINE_FEED);
        writer.append(
                "Content-Disposition: form-data; name=\"" + fieldName
                        + "\"; filename=\"" + fileName + "\"")
                .append(LINE_FEED);
        writer.append(
                "Content-Type: "
                        + URLConnection.guessContentTypeFromName(fileName))
                .append(LINE_FEED);
        writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
        writer.append(LINE_FEED);
        writer.flush();

        FileInputStream inputStream = new FileInputStream(uploadFile);
        byte[] buffer = new byte[4096];
        int bytesRead = -1;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        outputStream.flush();
        inputStream.close();

        writer.append(LINE_FEED);
        writer.flush();
    }

    /**
     * Adds a header field to the request.
     *
     * @param name  - name of the header field
     * @param value - value of the header field
     */
    public void addHeaderField(String name, String value) {
        writer.append(name + ": " + value).append(LINE_FEED);
        writer.flush();
    }

    /**
     * Completes the request and receives response from the server.
     *
     * @return a list of Strings as response in case the server returned
     * status OK, otherwise an exception is thrown.
     * @throws IOException
     */
    public List<String> finish() throws IOException {
        List<String> response = new ArrayList<String>();

        writer.append(LINE_FEED).flush();
        writer.append("--" + boundary + "--").append(LINE_FEED);
        writer.close();

        // checks server's status code first
        int status = httpConn.getResponseCode();
        if (status == HttpURLConnection.HTTP_OK) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    httpConn.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                response.add(line);
            }
            reader.close();
            httpConn.disconnect();
        } else {
            throw new IOException("Server returned non-OK status: " + status);
        }

        return response;
    }
}

SỬ DỤNG

private void uploadMedia() {
        try {

            String charset = "UTF-8";
            File uploadFile1 = new File("/sdcard/myvideo.mp4");
            String requestURL = Data.BASE_URL+Data.URL_UPLOAD_REACTION_TEST;

            MultipartUtility multipart = new MultipartUtility(requestURL, charset);

//            multipart.addHeaderField("User-Agent", "CodeJava");
//            multipart.addHeaderField("Test-Header", "Header-Value");

            multipart.addFormField("friend_id", "Cool Pictures");
            multipart.addFormField("userid", "Java,upload,Spring");

            multipart.addFilePart("uploadedfile", uploadFile1);

            List<String> response = multipart.finish();

            Log.v("rht", "SERVER REPLIED:");

            for (String line : response) {
                Log.v("rht", "Line : "+line);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

Mã PHP để chấp nhận tải lên

<?php

    $friend_id = $_REQUEST['friend_id'];
    $userid = $_REQUEST['userid'];

    echo 'friend_id : '.$friend_id. ' userid '.$userid;

    move_uploaded_file($_FILES['uploadedfile']['tmp_name'], "./uploads/".$_FILES["uploadedfile"]["name"]);

?>

Đối với ranh giới này, mã của tôi đã ném 400 ranh giới Yêu cầu sai = "===" + System.currentTimeMillis () + "==="; Sau đó, tôi đã thay đổi ranh giới là ranh giới = "---" + System.currentTimeMillis (); Sau đó, yêu cầu đã được phân tích cú pháp chính xác ở back-end.
Prashant

tại sao điều này lại phức tạp như vậy ...? Không có chính xác một câu hỏi. Chỉ khó chịu là nó phải mất rất nhiều để làm điều này trong môi trường này.
Neo42,

Tôi đã sử dụng điều này thành công, nhưng phải xóa phần phụ cuối cùng (LINEFEED) trong addFilePart (). Cảm ơn.
David Wood

6

Dễ dàng hơn, nhẹ hơn (32k) và nhiều hiệu suất hơn:

Thư viện ứng dụng khách Http không đồng bộ của Android: http://loopj.com/android-async-http/

Thực hiện:

Cách gửi BÀI ĐĂNG “nhiều phần / dữ liệu biểu mẫu” trong Android với Volley


lib loopj asynchttpclient thật tuyệt vời. Nhưng nó không thành công nếu bạn muốn upload nhiều file cùng một lúc: S
Sebastian Breit

@Perroloco, bạn có thể phải tăng thời gian chờ để thành công với các tệp lớn / nhiều. Lượng thời gian chờ mặc định có thể quá thấp. Bạn đã thử điều này với khoảng thời gian chờ lâu hơn chưa? Bởi vì tôi đã thành công trong việc gửi nhiều file với loopj cùng một lúc ...
Chris

thanx @Chris, tôi đã thử nhưng vẫn không thành công .. Tôi đã quản lý bằng cách thực hiện nhiều yêu cầu.
Sebastian Breit

1
loopj không có tùy chọn để hiển thị tiến trình nhưng tải tệp lên rất tốt
vuhung3990

cảm ơn @Hpsatum tìm kiếm từ 6 giờ trước kết thúc, điều này hoạt động tốt !!
Iftikar Urrhman Khan,

3

Thử cái này:

    public void SendMultipartFile() {
    Log.d(TAG, "UPLOAD: SendMultipartFile");
    DefaultHttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost( <url> );

    File file = new File("/sdcard/spider.jpg");

    Log.d(TAG, "UPLOAD: setting up multipart entity");

    MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
    Log.d(TAG, "UPLOAD: file length = " + file.length());
    Log.d(TAG, "UPLOAD: file exist = " + file.exists());

    try {
        mpEntity.addPart("datafile", new FileBody(file, "application/octet"));
        mpEntity.addPart("id", new StringBody("1"));
    } catch (UnsupportedEncodingException e1) {
        Log.d(TAG, "UPLOAD: UnsupportedEncodingException");
        e1.printStackTrace();
    }

    httppost.setEntity(mpEntity);
    Log.d(TAG, "UPLOAD: executing request: " + httppost.getRequestLine());
    Log.d(TAG, "UPLOAD: request: " + httppost.getEntity().getContentType().toString());


    HttpResponse response;
    try {
        Log.d(TAG, "UPLOAD: about to execute");
        response = httpclient.execute(httppost);
        Log.d(TAG, "UPLOAD: executed");
        HttpEntity resEntity = response.getEntity();
        Log.d(TAG, "UPLOAD: respose code: " + response.getStatusLine().toString());
        if (resEntity != null) {
            Log.d(TAG, "UPLOAD: " + EntityUtils.toString(resEntity));
        }
        if (resEntity != null) {
            resEntity.consumeContent();
        }
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

1
điều này cần lib của bên thứ 3 giống như ví dụ trước
Lassi Kinnunen

sử dụng biên dịch 'org.apache.httpcomponents: httpmime: 4.3.4' biên dịch 'org.apache.httpcomponents: httpcore: 4.3.2' cho các phụ thuộc studio android
Tyler Davis

3

Tôi rất khuyên bạn nên Loopj.

Tôi đã sử dụng thành công nó để tải lên nhiều tệp cùng một lúc, bao gồm các loại kịch câm khác nhau. Đơn giản chỉ cần làm điều này:

File myVideo = new File("/path/to/myvideo.mp4");
File myPic = new File("/path/to/mypic.jpg");
RequestParams params = new RequestParams();
try {
  params.put("profile_picture", myPic);
  params.put("my_video", myVideo);
} catch(FileNotFoundException e) {}

Đối với các tệp lớn hoặc nhiều tệp, bạn có thể phải tăng thời lượng chờ nếu không thì thời gian chờ mặc định được sử dụng có thể quá ngắn:

client.setTimeout(500000) //make this the appropriate timeout in milliseconds

Vui lòng xem các liên kết này để biết mô tả đầy đủ về loopj và cách sử dụng nó, cho đến nay thư viện http không đồng bộ dễ dàng nhất mà tôi đã xem qua:

http://loopj.com/android-async-http/ http://loopj.com/android-async-http/doc/com/loopj/android/http/AsyncHttpClient.html


1

Xóa tất cả phần phụ thuộc httpclient, httpmime của bạn và thêm phần phụ thuộc này compile 'commons-httpclient:commons-httpclient:3.1'. Sự phụ thuộc này đã được tích hợp trong MultipartRequestEntity để bạn có thể dễ dàng tải một hoặc nhiều tệp lên máy chủ

public class FileUploadUrlConnection extends AsyncTask<String, String, String> {
private Context context;
private String url;
private List<File> files;

public FileUploadUrlConnection(Context context, String url, List<File> files) {
    this.context = context;
    this.url = url;
    this.files = files;
}

@Override
protected String doInBackground(String... params) {

    HttpClient client = new HttpClient();
    PostMethod post = new PostMethod(url);
    HttpClientParams connectionParams = new HttpClientParams();

    post.setRequestHeader(// Your header goes here );

    try {
        Part[] parts = new Part[files.size()];
        for (int i=0; i<files.size(); i++) {
            Part part = new FilePart(files.get(i).getName(), files.get(i));
            parts[i] = part;
        }

        MultipartRequestEntity entity = new MultipartRequestEntity(parts, connectionParams);

        post.setRequestEntity(entity);

        int statusCode = client.executeMethod(post);
        String response = post.getResponseBodyAsString();

        Log.v("Multipart "," "+response);
        if(statusCode == 200) {
            return response;
        }
    } catch (IOException e) {
        e.printStackTrace();
    } 
 return null;
}

Bạn cũng có thể thêm yêu cầu và thời gian chờ phản hồi

client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000);
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 10000);

1
public class Multipart{
    private final Map<String, String> headrs;
    private String url;
    private HttpURLConnection con;
    private OutputStream os;

    private String delimiter = "--";
    private String boundary = "TRR" + Long.toString(System.currentTimeMillis()) + "TRR";

    public Multipart (String url, Map<String, String> headers) {
        this.url = url;
        this.headrs = headers;
    }

    public void connectForMultipart() throws Exception {
        con = (HttpURLConnection) (new URL(url)).openConnection();
        con.setRequestMethod("POST");
        con.setDoInput(true);
        con.setDoOutput(true);
        con.setRequestProperty("Connection", "Keep-Alive");
        for (Map.Entry<String, String> entry : headrs.entrySet()) {
            con.setRequestProperty(entry.getKey(), entry.getValue());
        }
        con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
        con.connect();
        os = con.getOutputStream();
    }

    public void addFormPart(String paramName, String value) throws Exception {
        writeParamData(paramName, value);
    }

    public void addFilePart(String paramName, String fileName, byte[] data) throws Exception {
        os.write((delimiter + boundary + "\r\n").getBytes());
        os.write(("Content-Disposition: form-data; name=\"" + paramName + "\"; filename=\"" + fileName + "\"\r\n").getBytes());
        os.write(("Content-Type: application/octet-stream\r\n").getBytes());
        os.write(("Content-Transfer-Encoding: binary\r\n").getBytes());
        os.write("\r\n".getBytes());

        os.write(data);

        os.write("\r\n".getBytes());
    }

    public void finishMultipart() throws Exception {
        os.write((delimiter + boundary + delimiter + "\r\n").getBytes());
    }


    public String getResponse() throws Exception {
        InputStream is = con.getInputStream();
        byte[] b1 = new byte[1024];
        StringBuffer buffer = new StringBuffer();

        while (is.read(b1) != -1)
            buffer.append(new String(b1));

        con.disconnect();

        return buffer.toString();
    }


    private void writeParamData(String paramName, String value) throws Exception {


        os.write((delimiter + boundary + "\r\n").getBytes());
        os.write("Content-Type: text/plain\r\n".getBytes());//;charset=utf-8
        os.write(("Content-Disposition: form-data; name=\"" + paramName + "\"\r\n").getBytes());
        ;
        os.write(("\r\n" + value + "\r\n").getBytes());


    }
}

Sau đó gọi bên dưới

Multipart multipart = new Multipart(url__, map);
            multipart .connectForMultipart();
multipart .addFormPart(entry.getKey(), entry.getValue());
multipart .addFilePart(KeyName, "FileName", imagedata);
multipart .finishMultipart();

0

Tôi có thể giới thiệu thư viện Ion nó sử dụng 3 phụ thuộc và bạn có thể tìm thấy cả ba tệp jar tại hai trang web này:
https://github.com/koush/ion#jars (ion và androidasync)

https://code.google.com/p/google-gson/downloads/list (gson)

try {
   Ion.with(this, "http://www.urlthatyouwant.com/post/page")
   .setMultipartParameter("field1", "This is field number 1")
   .setMultipartParameter("field2", "Field 2 is shorter")
   .setMultipartFile("imagefile",
        new File(Environment.getExternalStorageDirectory()+"/testfile.jpg"))
   .asString()
   .setCallback(new FutureCallback<String>() {
        @Override
        public void onCompleted(Exception e, String result) {
             System.out.println(result);
        }});
   } catch(Exception e) {
     // Do something about exceptions
        System.out.println("exception: " + e);
   }

điều này sẽ chạy không đồng bộ và lệnh gọi lại sẽ được thực hiện trong chuỗi giao diện người dùng khi nhận được phản hồi. Tôi thực sự khuyên bạn nên truy cập https://github.com/koush/ion để biết thêm thông tin


0

Đây là một cách tiếp cận Đơn giản nếu bạn đang sử dụng thư viện AOSP Volley.

Mở rộng lớp học Request<T>như sau-

public class MultipartRequest extends Request<String> {
    private static final String FILE_PART_NAME = "file";
    private final Response.Listener<String> mListener;
    private final Map<String, File> mFilePart;
    private final Map<String, String> mStringPart;
    MultipartEntityBuilder entity = MultipartEntityBuilder.create();
    HttpEntity httpentity;

    public MultipartRequest(String url, Response.ErrorListener errorListener,
                            Response.Listener<String> listener, Map<String, File> file,
                            Map<String, String> mStringPart) {
        super(Method.POST, url, errorListener);
        mListener = listener;
        mFilePart = file;
        this.mStringPart = mStringPart;
        entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        buildMultipartEntity();
    }

    public void addStringBody(String param, String value) {
        mStringPart.put(param, value);
    }

    private void buildMultipartEntity() {
        for (Map.Entry<String, File> entry : mFilePart.entrySet()) {
            // entity.addPart(entry.getKey(), new FileBody(entry.getValue(), ContentType.create("image/jpeg"), entry.getKey()));
            try {
                entity.addBinaryBody(entry.getKey(), Utils.toByteArray(new FileInputStream(entry.getValue())), ContentType.create("image/jpeg"), entry.getKey() + ".JPG");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        for (Map.Entry<String, String> entry : mStringPart.entrySet()) {
            if (entry.getKey() != null && entry.getValue() != null) {
                entity.addTextBody(entry.getKey(), entry.getValue());
            }
        }
    }

    @Override
    public String getBodyContentType() {
        return httpentity.getContentType().getValue();
    }

    @Override
    public byte[] getBody() throws AuthFailureError {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            httpentity = entity.build();
            httpentity.writeTo(bos);
        } catch (IOException e) {
            VolleyLog.e("IOException writing to ByteArrayOutputStream");
        }
        return bos.toByteArray();
    }

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        Log.d("Response", new String(response.data));
        return Response.success(new String(response.data), getCacheEntry());
    }

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

Bạn có thể tạo và thêm một yêu cầu như-

Map<String, String> params = new HashMap<>();
        params.put("name", name.getText().toString());
        params.put("email", email.getText().toString());
        params.put("user_id", appPreferences.getInt( Utils.PROPERTY_USER_ID, -1) + "");
        params.put("password", password.getText().toString());
        params.put("imageName", pictureName);
        Map<String, File> files = new HashMap<>();
        files.put("photo", new File(Utils.LOCAL_RESOURCE_PATH + pictureName));
        MultipartRequest multipartRequest = new MultipartRequest(Utils.BASE_URL + "editprofile/" + appPreferences.getInt(Utils.PROPERTY_USER_ID, -1), new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // TODO Auto-generated method stub
                Log.d("Error: ", error.toString());
                FugaDialog.showErrorDialog(ProfileActivity.this);
            }
        }, new Response.Listener<String>() {
            @Override
            public void onResponse(String jsonResponse) {
                JSONObject response = null;
                try {
                    Log.d("jsonResponse: ", jsonResponse);
                    response = new JSONObject(jsonResponse);

                } catch (JSONException e) {
                    e.printStackTrace();
                }
                try {
                    if (response != null && response.has("statusmessage") && response.getBoolean("statusmessage")) {
                        updateLocalRecord();

                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                FugaDialog.dismiss();
            }

        }, files, params);
        RequestQueue queue = Volley.newRequestQueue(this);
        queue.add(multipartRequest);

0

Đối với hậu thế, tôi không thấy okhttp được đề cập. Bài liên quan.

Về cơ bản, bạn xây dựng phần thân bằng cách sử dụng MultipartBody.Builder, sau đó đăng nội dung này trong một yêu cầu.

Ví dụ trong kotlin:

    val body = MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart(
                "file", 
                file.getName(),
                RequestBody.create(MediaType.parse("image/png"), file)
            )
            .addFormDataPart("timestamp", Date().time.toString())
            .build()

    val request = Request.Builder()
            .url(url)
            .post(body)
            .build()

    httpClient.newCall(request).enqueue(object : okhttp3.Callback {
        override fun onFailure(call: Call?, e: IOException?) {
            ...
        }

        override fun onResponse(call: Call?, response: Response?) {
            ...
        }
    })

0

Bạn có thể sử dụng GentleRequest, đây là thư viện nhẹ để thực hiện các yêu cầu http (TUYÊN BỐ MIỄN TRỪ: Tôi là tác giả):

Connections connections = new HttpConnections();
Binary binary = new PacketsBinary(new 
BufferedInputStream(new FileInputStream(file)), 
   file.length());
//Content-Type is set to multipart/form-data; boundary= 
//{generated by multipart object}
MultipartForm multipart = new HttpMultipartForm(
    new HttpFormPart("user", "aplication/json", 
       new JSONObject().toString().getBytes()),
    new HttpFormPart("java", "java.png", "image/png", 
       binary.content()));
Response response = connections.response(new 
    PostRequest(url, multipart));
if (response.hasSuccessCode()) {
    byte[] raw = response.body().value();
    String string = response.body().stringValue();
    JSONOBject json = response.body().jsonValue();
 } else {

 }

Vui lòng kiểm tra nó: https://github.com/Iprogrammerr/Gooter-Request

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.