HttpURLConnection के साथ POST का उपयोग करके फाइलें भेजना


124

चूंकि एंड्रॉइड डेवलपर्स उपयोग करने की सलाह देते हैंHttpURLConnection वर्ग , इसलिए मैं सोच रहा था कि कोई भी मुझे एक अच्छा उदाहरण प्रदान कर सकता है कि कैसे एक बिटमैप "फ़ाइल" (वास्तव में एक इन-मेमोरी स्ट्रीम) को पोस्ट करने के लिए एक अपाचे एचटीटीपी सर्वर के माध्यम से। मुझे कुकीज़ या प्रमाणीकरण या कुछ भी जटिल नहीं है, लेकिन मैं सिर्फ एक विश्वसनीय और तर्क कार्यान्वयन करना चाहता हूं। सभी उदाहरण जो मैंने अपने आस-पास देखे हैं, वे अधिक "जैसे चलो यह कोशिश करते हैं और शायद यह काम करता है"।

अभी, मेरे पास यह कोड है:

URL url;
HttpURLConnection urlConnection = null;
try {
    url = new URL("http://example.com/server.cgi");

    urlConnection = (HttpURLConnection) url.openConnection();

} catch (Exception e) {
    this.showDialog(getApplicationContext(), e.getMessage());
}
finally {
    if (urlConnection != null)
    {
        urlConnection.disconnect();
    }
}

जहां showDialog को केवल एक AlertDialog(अमान्य URL के मामले में?) प्रदर्शित करना चाहिए ।

अब, मान लें कि मैं एक बिटमैप उत्पन्न करता हूं: Bitmap image = this.getBitmap()अंदर से प्राप्त नियंत्रण के अंदर Viewऔर मैं इसे POST के माध्यम से भेजना चाहता हूं। ऐसी चीज हासिल करने के लिए उचित प्रक्रिया क्या होगी? मुझे किन वर्गों का उपयोग करने की आवश्यकता है? क्या मैं इस उदाहरणHttpPost में उपयोग कर सकता हूं ? यदि हां, तो मैं अपने बिटमैप के लिए निर्माण कैसे करूंगा ? मुझे लगता है कि डिवाइस पर किसी फ़ाइल में बिटमैप को संग्रहीत करने के लिए इसे बगावत करना आवश्यक होगा।InputStreamEntity


मुझे यह भी उल्लेख करना चाहिए कि मुझे वास्तव में मूल बिटमैप के हर अनछुए पिक्सेल को सर्वर पर भेजने की आवश्यकता है, इसलिए मैं इसे जेपीईजी में परिवर्तित नहीं कर सकता।


जवाबों:


194

मुझे इस बात का कोई अंदाजा नहीं है कि HttpURLConnectionक्‍लास ने फाइल रैपर को मैनुअली कंपोज़ किए बिना फाइल भेजने का कोई साधन क्‍यों नहीं दिया। यहाँ मैं क्या कर रहा हूँ, लेकिन अगर कोई बेहतर समाधान जानता है, तो कृपया मुझे बताएँ।

इनपुट डेटा:

Bitmap bitmap = myView.getBitmap();

स्थिर सामान:

String attachmentName = "bitmap";
String attachmentFileName = "bitmap.bmp";
String crlf = "\r\n";
String twoHyphens = "--";
String boundary =  "*****";

अनुरोध सेट करें:

HttpURLConnection httpUrlConnection = null;
URL url = new URL("http://example.com/server.cgi");
httpUrlConnection = (HttpURLConnection) url.openConnection();
httpUrlConnection.setUseCaches(false);
httpUrlConnection.setDoOutput(true);

httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.setRequestProperty("Connection", "Keep-Alive");
httpUrlConnection.setRequestProperty("Cache-Control", "no-cache");
httpUrlConnection.setRequestProperty(
    "Content-Type", "multipart/form-data;boundary=" + this.boundary);

सामग्री आवरण प्रारंभ करें:

DataOutputStream request = new DataOutputStream(
    httpUrlConnection.getOutputStream());

request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
request.writeBytes("Content-Disposition: form-data; name=\"" +
    this.attachmentName + "\";filename=\"" + 
    this.attachmentFileName + "\"" + this.crlf);
request.writeBytes(this.crlf);

में परिवर्तित Bitmapकरें ByteBuffer:

//I want to send only 8 bit black & white bitmaps
byte[] pixels = new byte[bitmap.getWidth() * bitmap.getHeight()];
for (int i = 0; i < bitmap.getWidth(); ++i) {
    for (int j = 0; j < bitmap.getHeight(); ++j) {
        //we're interested only in the MSB of the first byte, 
        //since the other 3 bytes are identical for B&W images
        pixels[i + j] = (byte) ((bitmap.getPixel(i, j) & 0x80) >> 7);
    }
}

request.write(pixels);

अंतिम सामग्री आवरण:

request.writeBytes(this.crlf);
request.writeBytes(this.twoHyphens + this.boundary + 
    this.twoHyphens + this.crlf);

फ्लश आउटपुट बफर:

request.flush();
request.close();

प्रतिक्रिया हासिल करो:

InputStream responseStream = new 
    BufferedInputStream(httpUrlConnection.getInputStream());

BufferedReader responseStreamReader = 
    new BufferedReader(new InputStreamReader(responseStream));

String line = "";
StringBuilder stringBuilder = new StringBuilder();

while ((line = responseStreamReader.readLine()) != null) {
    stringBuilder.append(line).append("\n");
}
responseStreamReader.close();

String response = stringBuilder.toString();

प्रतिक्रिया स्ट्रीम बंद करें:

responseStream.close();

कनेक्शन बंद करें:

httpUrlConnection.disconnect();

पुनश्च: बेशक मुझे private class AsyncUploadBitmaps extends AsyncTask<Bitmap, Void, String>एंड्रॉइड प्लेटफॉर्म को खुश करने के लिए अनुरोध को लपेटना पड़ा , क्योंकि यह मुख्य धागे पर नेटवर्क अनुरोधों को पसंद नहीं करता है।


6
अंत में इस प्रश्न के लिए एक पूरी तरह से समझाया गया उत्तर! धन्यवाद! BTW, मुझे यह लेख केवल Android Developers Blog ( android-developers.blogspot.com/2011/09/… ) से मिला, जहां वे Apache HTTPClient पर HTTPURLConnection का उपयोग करने का सुझाव देते हैं। चीयर्स!
एंड्रेस पचोन

पुनश्च: के अनुसार इस `[त्रुटि] => 3` का मतलब है कि" अपलोड की गई फ़ाइल केवल आंशिक रूप से अपलोड किया गया था ", तो मैं यह मान सकते हैं कुछ बफरिंग मुद्दों देखते हैं कि, लेकिन मैं कैसे इस तरह डिबग / ठीक कुछ करने के लिए पता नहीं है ।
मिहाई टोडर

1
मेरी टिप्पणी ऊपर देखें। आपको उन्हें urlचर में जोड़ने की जरूरत है , जैसे URL url = new URL("http://example.com/?param1=val1&param2=val2");:। आप जितनी चाहें जोड़ सकते हैं (हालांकि मुझे लगता है कि कुछ सीमाएं हैं)।
मिहाई टोडर

बहुत बढ़िया, बस एक बात याद आती है: कि responseStreamReader कोशिश / पकड़ के अंत में बंद होना चाहिए। इस तरह: {All Your CODE} catch (IOException e) {e.printStackTrace () देखें; } अंत में {if (कनेक्शन! = null) कनेक्शन .isconnect (); try {if (responseStreamReader! = null) responseStreamReader.close (); } पकड़ (IOException e) {e.printStackTrace (); }}
फ्लोरियनबी

2
एकदम सही जवाब! मैं पर एक नज़र लेने के लिए सुझाव है कि रूपों के बारे में इस w3.org डॉक्स
pippo

68

मैंने वास्तव में मल्टीपार्ट एनीटिटी का उपयोग करके HttpURLConnection का उपयोग करके फाइल भेजने का एक बेहतर तरीका पाया

private static String multipost(String urlString, MultipartEntity reqEntity) {
    try {
        URL url = new URL(urlString);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(10000);
        conn.setConnectTimeout(15000);
        conn.setRequestMethod("POST");
        conn.setUseCaches(false);
        conn.setDoInput(true);
        conn.setDoOutput(true);

        conn.setRequestProperty("Connection", "Keep-Alive");
        conn.addRequestProperty("Content-length", reqEntity.getContentLength()+"");
        conn.addRequestProperty(reqEntity.getContentType().getName(), reqEntity.getContentType().getValue());

        OutputStream os = conn.getOutputStream();
        reqEntity.writeTo(conn.getOutputStream());
        os.close();
        conn.connect();

        if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
            return readStream(conn.getInputStream());
        }

    } catch (Exception e) {
        Log.e(TAG, "multipart post error " + e + "(" + urlString + ")");
    }
    return null;        
}

private static String readStream(InputStream in) {
    BufferedReader reader = null;
    StringBuilder builder = new StringBuilder();
    try {
        reader = new BufferedReader(new InputStreamReader(in));
        String line = "";
        while ((line = reader.readLine()) != null) {
            builder.append(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return builder.toString();
} 

मान लें कि आप बिटमैप डेटा के साथ एक छवि अपलोड कर रहे हैं:

    Bitmap bitmap = ...;
    String filename = "filename.png";
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
    ContentBody contentPart = new ByteArrayBody(bos.toByteArray(), filename);

    MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
    reqEntity.addPart("picture", contentPart);
    String response = multipost("http://server.com", reqEntity);

और वोइला! आपके पोस्ट डेटा में आपके सर्वर पर फ़ाइल नाम और पथ के साथ चित्र फ़ील्ड होगा।


1
मुझे लगता है कि आप con.disconnect () नहीं कह रहे हैं, क्या यह जानबूझकर है?
जेरीटॉइल

1
@MihaiTodor आप किसी भी तरह नेटवर्क पर डेटा की मात्रा को कम करने के लिए बिटमैप को एक फ़ाइल में संपीड़ित करना चाहेंगे।
स्टील्कोप्टर

5
आपको सामग्री-लंबाई शीर्ष लेख को सीधे सेट करने के बजाय setFixedLengthStreamingMode (reqEntity.getContentLength ()) को कॉल करना चाहिए। इस तरह से सॉकेट पर भेजने से पहले आपका डेटा बफ़र नहीं किया जाता है (कम से कम नए उपकरणों पर, एंड्रॉइड 2.3 पर या इससे कम लगता है कि वे किसी भी तरह से बफ़र्ड हो जाते हैं)। मैंने पुराने उपकरणों पर बफरिंग इश्यू को ट्रांसपोर्ट के रूप में okhttp का उपयोग करके तय किया और वह काम करता है।
मैट वोल्फ

16
बहुत बुरा MultipartEntity Android SDK
mente

2
@mente इसे httpmime के साथ बंडल किया गया है। मैं इसे ग्रैडल निर्भरता के रूप में उपयोग करता हूं: org.apache.httpcompords: httpmime: 4.1.1
david.perez

63

MultipartUtilityसरल तरीके से उपयोग करने वाले कुछ पैरामीटर के साथ सर्वर पर फ़ाइल अपलोड करने के लिए।

MultipartUtility.java

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);
        Log.e("URL", "URL : " + requestURL.toString());
        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 String finish() throws IOException {
        StringBuffer response = new StringBuffer();

        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.append(line);
            }
            reader.close();
            httpConn.disconnect();
        } else {
            throw new IOException("Server returned non-OK status: " + status);
        }

        return response.toString();
    }
}

करने के लिए uploadआप fileपैरामीटर के साथ साथ।

नोट: प्रतिक्रिया प्राप्त करने के लिए इस कोड को गैर-यूआई-थ्रेड में नीचे रखें।

String charset = "UTF-8";
String requestURL = "YOUR_URL";

MultipartUtility multipart = new MultipartUtility(requestURL, charset);
multipart.addFormField("param_name_1", "param_value");
multipart.addFormField("param_name_2", "param_value");
multipart.addFormField("param_name_3", "param_value");
multipart.addFilePart("file_param_1", new File(file_path));
String response = multipart.finish(); // response from server.

14

जयदीपसिंह ज़ला का समाधान मेरे लिए काम नहीं आया, मुझे नहीं पता कि यह समाधान के करीब क्यों लगता है।

इसलिए मिहई टोडर के महान समाधान और स्पष्टीकरण के साथ इस एक को विलय करना , इस वर्ग का परिणाम है जो वर्तमान में मेरे लिए काम करता है। अगर यह किसी की मदद करता है:

MultipartUtility2V.java

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;

public class MultipartUtilityV2 {
    private HttpURLConnection httpConn;
    private DataOutputStream request;
    private final String boundary =  "*****";
    private final String crlf = "\r\n";
    private final String twoHyphens = "--";

    /**
     * This constructor initializes a new HTTP POST request with content type
     * is set to multipart/form-data
     *
     * @param requestURL
     * @throws IOException
     */
    public MultipartUtilityV2(String requestURL)
            throws IOException {

        // creates a unique boundary based on time stamp
        URL url = new URL(requestURL);
        httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setUseCaches(false);
        httpConn.setDoOutput(true); // indicates POST method
        httpConn.setDoInput(true);

        httpConn.setRequestMethod("POST");
        httpConn.setRequestProperty("Connection", "Keep-Alive");
        httpConn.setRequestProperty("Cache-Control", "no-cache");
        httpConn.setRequestProperty(
                "Content-Type", "multipart/form-data;boundary=" + this.boundary);

        request =  new DataOutputStream(httpConn.getOutputStream());
    }

    /**
     * Adds a form field to the request
     *
     * @param name  field name
     * @param value field value
     */
    public void addFormField(String name, String value)throws IOException  {
        request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
        request.writeBytes("Content-Disposition: form-data; name=\"" + name + "\""+ this.crlf);
        request.writeBytes("Content-Type: text/plain; charset=UTF-8" + this.crlf);
        request.writeBytes(this.crlf);
        request.writeBytes(value+ this.crlf);
        request.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();
        request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
        request.writeBytes("Content-Disposition: form-data; name=\"" +
                fieldName + "\";filename=\"" +
                fileName + "\"" + this.crlf);
        request.writeBytes(this.crlf);

        byte[] bytes = Files.readAllBytes(uploadFile.toPath());
        request.write(bytes);
    }

    /**
     * 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 String finish() throws IOException {
        String response ="";

        request.writeBytes(this.crlf);
        request.writeBytes(this.twoHyphens + this.boundary +
                this.twoHyphens + this.crlf);

        request.flush();
        request.close();

        // checks server's status code first
        int status = httpConn.getResponseCode();
        if (status == HttpURLConnection.HTTP_OK) {
            InputStream responseStream = new
                    BufferedInputStream(httpConn.getInputStream());

            BufferedReader responseStreamReader =
                    new BufferedReader(new InputStreamReader(responseStream));

            String line = "";
            StringBuilder stringBuilder = new StringBuilder();

            while ((line = responseStreamReader.readLine()) != null) {
                stringBuilder.append(line).append("\n");
            }
            responseStreamReader.close();

            response = stringBuilder.toString();
            httpConn.disconnect();
        } else {
            throw new IOException("Server returned non-OK status: " + status);
        }

        return response;
    }
}

1
यह समाधान है जो केवल मेरे लिए काम करता है। आपका बहुत बहुत धन्यवाद।
युकेल बेयराम

3

इस उत्तर https://stackoverflow.com/a/33149413/6481542 ने मुझे 90% रास्ते एक विकास Django सर्वर पर बड़ी फ़ाइलों को अपलोड करने के साथ मिल गए, लेकिन मुझे काम करने के लिए setFixedLengthStreamingMode का उपयोग करना पड़ा । उस सामग्री को लिखने से पहले सामग्री-लंबाई निर्धारित करने की आवश्यकता होती है, इस प्रकार उपरोक्त उत्तर के एक महत्वपूर्ण पुन: लिखने की आवश्यकता होती है। यहाँ मेरा अंतिम परिणाम है

public class MultipartLargeUtility {
    private final String boundary;
    private static final String LINE_FEED = "\r\n";
    private HttpURLConnection httpConn;
    private String charset;
    private OutputStream outputStream;
    private PrintWriter writer;
    private final int maxBufferSize = 4096;
    private long contentLength = 0;
    private URL url;

    private List<FormField> fields;
    private List<FilePart> files;

    private class FormField {
        public String name;
        public String value;

        public FormField(String name, String value) {
            this.name = name;
            this.value = value;
        }
    }

    private class FilePart {
        public String fieldName;
        public File uploadFile;

        public FilePart(String fieldName, File uploadFile) {
            this.fieldName = fieldName;
            this.uploadFile = uploadFile;
        }
    }

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

        // creates a unique boundary based on time stamp
        boundary = "===" + System.currentTimeMillis() + "===";
        url = new URL(requestURL);
        fields = new ArrayList<>();
        files = new ArrayList<>();

        if (requireCSRF) {
            getCSRF();
        }
    }

    /**
     * Adds a form field to the request
     *
     * @param name  field name
     * @param value field value
     */
    public void addFormField(String name, String value)
            throws UnsupportedEncodingException {
        String fieldContent = "--" + boundary + LINE_FEED;
        fieldContent += "Content-Disposition: form-data; name=\"" + name + "\"" + LINE_FEED;
        fieldContent += "Content-Type: text/plain; charset=" + charset + LINE_FEED;
        fieldContent += LINE_FEED;
        fieldContent += value + LINE_FEED;
        contentLength += fieldContent.getBytes(charset).length;
        fields.add(new FormField(name, value));
    }

    /**
     * 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();

        String fieldContent = "--" + boundary + LINE_FEED;
        fieldContent += "Content-Disposition: form-data; name=\"" + fieldName
                + "\"; filename=\"" + fileName + "\"" + LINE_FEED;
        fieldContent += "Content-Type: "
                + URLConnection.guessContentTypeFromName(fileName) + LINE_FEED;
        fieldContent += "Content-Transfer-Encoding: binary" + LINE_FEED;
        fieldContent += LINE_FEED;
        // file content would go here
        fieldContent += LINE_FEED;
        contentLength += fieldContent.getBytes(charset).length;
        contentLength += uploadFile.length();
        files.add(new FilePart(fieldName, uploadFile));
    }

    /**
     * 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>();
        String content = "--" + boundary + "--" + LINE_FEED;
        contentLength += content.getBytes(charset).length;

        if (!openConnection()) {
            return response;
        }

        writeContent();

        // 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;
    }

    private boolean getCSRF()
            throws IOException {
        /// First, need to get CSRF token from server
        /// Use GET request to get the token
        CookieManager cookieManager = new CookieManager();
        CookieHandler.setDefault(cookieManager);
        HttpURLConnection conn = null;

        conn = (HttpURLConnection) url.openConnection();

        conn.setUseCaches(false); // Don't use a Cached Copy
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Connection", "Keep-Alive");
        conn.getContent();
        conn.disconnect();

        /// parse the returned object for the CSRF token
        CookieStore cookieJar = cookieManager.getCookieStore();
        List<HttpCookie> cookies = cookieJar.getCookies();
        String csrf = null;
        for (HttpCookie cookie : cookies) {
            Log.d("cookie", "" + cookie);
            if (cookie.getName().equals("csrftoken")) {
                csrf = cookie.getValue();
                break;
            }
        }
        if (csrf == null) {
            Log.d(TAG, "Unable to get CSRF");
            return false;
        }
        Log.d(TAG, "Received cookie: " + csrf);

        addFormField("csrfmiddlewaretoken", csrf);
        return true;
    }

    private boolean openConnection()
            throws IOException {
        httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setUseCaches(false);
        httpConn.setDoOutput(true);    // indicates POST method
        httpConn.setDoInput(true);
        //httpConn.setRequestProperty("Accept-Encoding", "identity");
        httpConn.setFixedLengthStreamingMode(contentLength);
        httpConn.setRequestProperty("Connection", "Keep-Alive");
        httpConn.setRequestProperty("Content-Type",
                "multipart/form-data; boundary=" + boundary);
        outputStream = new BufferedOutputStream(httpConn.getOutputStream());
        writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
                true);
        return true;
    }

    private void writeContent()
            throws IOException {

        for (FormField field : fields) {
            writer.append("--" + boundary).append(LINE_FEED);
            writer.append("Content-Disposition: form-data; name=\"" + field.name + "\"")
                    .append(LINE_FEED);
            writer.append("Content-Type: text/plain; charset=" + charset).append(
                    LINE_FEED);
            writer.append(LINE_FEED);
            writer.append(field.value).append(LINE_FEED);
            writer.flush();
        }

        for (FilePart filePart : files) {
            String fileName = filePart.uploadFile.getName();
            writer.append("--" + boundary).append(LINE_FEED);
            writer.append(
                    "Content-Disposition: form-data; name=\"" + filePart.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(filePart.uploadFile);
            int bufferSize = Math.min(inputStream.available(), maxBufferSize);
            byte[] buffer = new byte[bufferSize];
            int bytesRead = -1;
            while ((bytesRead = inputStream.read(buffer, 0, bufferSize)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
            inputStream.close();
            writer.append(LINE_FEED);
            writer.flush();
        }

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

उपयोग काफी हद तक उपरोक्त उत्तर के समान है, लेकिन मैंने CSRF समर्थन को शामिल किया है जो कि Django रूपों के साथ डिफ़ॉल्ट रूप से उपयोग करता है

boolean useCSRF = true;
MultipartLargeUtility multipart = new MultipartLargeUtility(url, "UTF-8",useCSRF);
multipart.addFormField("param1","value");
multipart.addFilePart("filefield",new File("/path/to/file"));
List<String> response = multipart.finish();
Log.w(TAG,"SERVER REPLIED:");
for(String line : response) {
    Log.w(TAG, "Upload Files Response:::" + line);
}

2

Mihai के समाधान के आधार पर, अगर किसी को सर्वर पर छवियों को सहेजने की समस्या है जैसे मेरे सर्वर पर क्या हुआ। बिटमैप को बाइटबफ़र भाग में बदलें:

ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG,100,bos);
        byte[] pixels = bos.toByteArray();

1

मैंने इसका परीक्षण नहीं किया है, लेकिन आप PipedInputStream और PipedOutputStream का उपयोग करने का प्रयास कर सकते हैं। यह कुछ इस तरह लग सकता है:

final Bitmap bmp =  // your bitmap

// Set up Piped streams
final PipedOutputStream pos = new PipedOutputStream(new ByteArrayOutputStream());
final PipedInputStream pis = new PipedInputStream(pos);

// Send bitmap data to the PipedOutputStream in a separate thread
new Thread() {
    public void run() {
        bmp.compress(Bitmap.CompressFormat.PNG, 100, pos);
    }
}.start();

// Send POST request
try {
    // Construct InputStreamEntity that feeds off of the PipedInputStream
    InputStreamEntity reqEntity = new InputStreamEntity(pis, -1);

    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(url);
    reqEntity.setContentType("binary/octet-stream");
    reqEntity.setChunked(true);
    httppost.setEntity(reqEntity);
    HttpResponse response = httpclient.execute(httppost);
} catch (Exception e) {
    e.printStackTrace()
}

0

यहाँ मैंने पोस्ट अनुरोध का उपयोग करके फोटो अपलोड करने के लिए क्या किया है।

public void uploadFile(int directoryID, String filePath) {
    Bitmap bitmapOrg = BitmapFactory.decodeFile(filePath);
    ByteArrayOutputStream bao = new ByteArrayOutputStream();

    String upload_url = BASE_URL + UPLOAD_FILE;
    bitmapOrg.compress(Bitmap.CompressFormat.JPEG, 90, bao);

    byte[] data = bao.toByteArray();

    HttpClient httpClient = new DefaultHttpClient();
    HttpPost postRequest = new HttpPost(upload_url);
    MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

    try {
        // Set Data and Content-type header for the image
        FileBody fb = new FileBody(new File(filePath), "image/jpeg");
        StringBody contentString = new StringBody(directoryID + "");

        entity.addPart("file", fb);
        entity.addPart("directory_id", contentString);
        postRequest.setEntity(entity);

        HttpResponse response = httpClient.execute(postRequest);
        // Read the response
        String jsonString = EntityUtils.toString(response.getEntity());
        Log.e("response after uploading file ", jsonString);

    } catch (Exception e) {
        Log.e("Error in uploadFile", e.getMessage());
    }
}

नोट: इस कोड को पुस्तकालयों की आवश्यकता है इसलिए पुस्तकालयों को प्राप्त करने के लिए यहां दिए गए निर्देशों का पालन ​​करें ।


2
यह जानना अच्छा है कि नवीनतम संस्करण का उपयोग करने का एक तरीका है HttpClient(आपकी लिंक पुरानी है। इसके बजाय इसका उपयोग करें ), जिसे एंड्रॉइड लोग केवल बैकवर्ड संगतता के लिए रख रहे हैं, बजाय अंतर्निहित उपयोग के HttpURLConnection। दूसरी ओर, ऐसा लगता है कि इसे स्थापित करने के लिए अधिक कार्य की आवश्यकता है, इसलिए शायद यह प्रयास के लायक नहीं है।
मिहाई टॉड


0

मैंने ऊपर दिए गए समाधानों की कोशिश की और किसी ने भी मेरे लिए काम नहीं किया।

हालाँकि http://www.baeldung.com/httpclient-post-http-request । लाइन 6 पोस्ट मल्टीपार्ट अनुरोध सेकंड के भीतर काम किया

public void whenSendMultipartRequestUsingHttpClient_thenCorrect() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.example.com");

    MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    builder.addTextBody("username", "John");
    builder.addTextBody("password", "pass");
    builder.addBinaryBody("file", new File("test.txt"),
      ContentType.APPLICATION_OCTET_STREAM, "file.ext");

    HttpEntity multipart = builder.build();
    httpPost.setEntity(multipart);

    CloseableHttpResponse response = client.execute(httpPost);
    client.close();
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.