HTTP URL সংযোগের সাথে POST ব্যবহার করে ফাইল পাঠানো হচ্ছে


124

যেহেতু অ্যান্ড্রয়েড বিকাশকারীরা এটি ব্যবহার করার পরামর্শ দেয়HttpURLConnection ক্লাসটি , তাই আমি ভাবছিলাম যে কেউ কীভাবে আমাকে অ্যাপাচি এইচটিটিপি সার্ভারে পোষ্টের মাধ্যমে বিটম্যাপ "ফাইল" (আসলে একটি মেমরি স্ট্রিম) প্রেরণ করতে পারে তার জন্য একটি ভাল উদাহরণ সরবরাহ করতে পারে। আমি কুকিজ বা প্রমাণীকরণ বা জটিল কিছুতে আগ্রহী নই, তবে আমি কেবল একটি নির্ভরযোগ্য এবং যুক্তিযুক্ত বাস্তবায়ন করতে চাই। আমি এখানে যে উদাহরণগুলি দেখেছি সেগুলি আরও দেখতে "আসুন এটি চেষ্টা করুন এবং সম্ভবত এটি কার্যকর হয়" look

এখনই, আমার কাছে এই কোডটি রয়েছে:

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

যেখানে শোডায়ালগটি কেবল একটি প্রদর্শন করা উচিত AlertDialog একটি অবৈধ ইউআরএল প্রদর্শিত হবে?

এখন, আসুন আমি বলি যে আমি এটির মতো একটি বিটম্যাপ উত্পন্ন করি: Bitmap image = this.getBitmap()একটি নিয়ন্ত্রণ থেকে প্রাপ্ত Viewএবং আমি এটি পোস্টের মাধ্যমে পাঠাতে চাই। এই জাতীয় জিনিস অর্জনের যথাযথ পদ্ধতি কী হবে? আমার কোন ক্লাস ব্যবহার করা দরকার? আমি কি এই উদাহরণের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
অবশেষে এই প্রশ্নের পুরোপুরি ব্যাখ্যা করা উত্তর! ধন্যবাদ! বিটিডাব্লু, আমি স্রেফ এই নিবন্ধটি অ্যান্ড্রয়েড বিকাশকারী ব্লগ ( android-developers.blogspot.com/2011/09/… ) থেকে খুঁজে পেয়েছি যেখানে তারা অ্যাপাচি এইচটিপিটিসিপ্লায়েন্টের মাধ্যমে HTTPURL সংযোগ ব্যবহার করার পরামর্শ দেয়। চিয়ার্স!
অ্যান্ড্রেস পাচন

দ্রষ্টব্য: মতে এই , `[ত্রুটি] => 3` অর্থ হল," আপলোড করা ফাইলটি শুধুমাত্র আংশিকভাবে আপলোড করা হয়েছে ", তাই আমি অনুমান করতে পারেন কিছু বাফারিং সমস্যা আছে, কিন্তু আমি কিভাবে ভালো ডিবাগ / ফিক্স কিছু কোন ধারণা আছে ।
মিহাই টডর

1
আমার মন্তব্য ঠিক উপরে দেখুন। আপনি তাদের যুক্ত করতে হবে urlপরিবর্তনশীল যেমন: URL url = new URL("http://example.com/?param1=val1&param2=val2");। আপনি নিজের ইচ্ছামত যোগ করতে পারেন (যদিও আমি মনে করি কিছু সীমা আছে)।
মিহাই টডর

দুর্দান্ত, কেবল একটি জিনিস মিস করছে: সেই প্রতিক্রিয়া স্ট্রিম রিডারটি চেষ্টা / ধরা শেষের দিকে বন্ধ করে দেওয়া উচিত। এইভাবে: আপনার সমস্ত কোড} ধরা (আইওএক্সেপশন ই) {ই.প্রিন্টস্ট্যাকট্রেস () চেষ্টা করুন try } অবশেষে {যদি (সংযোগ! = নাল) সংযোগ.ডিসকনেক্ট (); চেষ্টা করুন {যদি (প্রতিক্রিয়া স্ট্রিমার্ডার! = নাল) প্রতিক্রিয়াপ্রবাহের পর্বতারোহণের তালিকা (); } ধরা (আইওএক্সেপশন ই) {ই.প্রিন্টস্ট্যাকট্রেস (); }}
ফ্লোরিয়ানবি


68

আমি প্রকৃতপক্ষে মাল্টিপার্টএন্টিটি ব্যবহার করে এইচটিপিআরএল সংযোগ ব্যবহার করে ফাইলগুলি প্রেরণের আরও ভাল উপায় খুঁজে পেয়েছি

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
আমি লক্ষ্য করেছি আপনি কান.ডিসকনেক্ট () কল করছেন না, এটি ইচ্ছাকৃত?
জেরিটোইল

1
@ মিহাইটোডর যেভাবেই নেটওয়ার্কের মাধ্যমে পাস করা ডেটার পরিমাণ হ্রাস করতে আপনি কোনও ফাইলের বিটম্যাপটি সংকুচিত করতে চাইবেন।
স্টিলথকপ্টার

5
আপনার সরাসরি কন্টেন্ট-দৈর্ঘ্যের শিরোনামটি সেট করার পরিবর্তে setFixedLengthStreamingMode (reqEntity.getContentLength ()) কল করা উচিত। সকেটে প্রেরণের আগে এই উপায়ে আপনার ডেটা বাফার করা হয়নি (কমপক্ষে নতুন ডিভাইসে, অ্যানড্রয়েড ২.৩ বা তার চেয়ে কম মনে হয় তারা যাই হোক বাফার হয়ে গেছে)। পরিবহন হিসাবে ওখিটপি ব্যবহার করে এবং এটি কার্যকর হিসাবে আমি পুরানো ডিভাইসে বাফারিংয়ের সমস্যাটি স্থির করেছি।
ম্যাট ওল্ফ

16
খুব খারাপ মাল্টিপার্টটিটিটি অ্যান্ড্রয়েড এসডিকে দিয়ে বান্ডিল হয় না
Mente 6'13

2
@ মেন্তে এটি httpsime এর সাথে বান্ডিল রয়েছে। আমি এটিকে গ্রেডল নির্ভরতা হিসাবে ব্যবহার করি: org.apache.http উপাদান: httpsime: 4.1.1
ডেভিড.প্রেজ

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% পথ পেয়েছিল, তবে এটি কাজ করতে আমাকে 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();
    }
}

উপরের উত্তরের মতো ব্যবহার মূলত একই, তবে আমি সিএসআরএফ সমর্থনটি অন্তর্ভুক্ত করেছি যা ফর্মের সাথে জ্যাঙ্গো ডিফল্টরূপে ব্যবহার করে

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

মিহাইয়ের সমাধানের উপর ভিত্তি করে, যদি কারও কাছে আমার সার্ভারে যা ঘটেছিল তার মতো সার্ভারে চিত্রগুলি সংরক্ষণ করতে সমস্যা হয়। বিটম্যাপটি বাইটবফার অংশে পরিবর্তন করুন:

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

1

আমি এটি পরীক্ষা করি নি তবে আপনি সম্ভবত পাইপডিনপুটস্ট্রিম এবং পাইপড আউটপুট স্ট্রিম ব্যবহারের চেষ্টা করতে পারেন। এটি দেখতে কিছুটা দেখতে লাগবে:

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();
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.