Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending MultipartEntity using HttpURLConnection

Tags:

java

c#

android

using the below code, i am able to send a large file to the server, but i cant seem to find out how send a text with the file.(send the file plus extra data(username, password..) for example). and also receive it at the server side.

FileInputStream fileInputStream = new FileInputStream(new File(
                   pathToOurFile));
URL url = new URL(urlServer);
            connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
           connection.setDoOutput(true);
            connection.setUseCaches(false);
            connection.setChunkedStreamingMode(1024);
            // Enable POST method
            connection.setRequestMethod("POST");

            connection.setRequestProperty("Connection", "Keep-Alive");
            connection.setRequestProperty("Content-Type",
                    "multipart/form-data;boundary=" + boundary);

            outputStream = new DataOutputStream(connection.getOutputStream());
            outputStream.writeBytes(twoHyphens + boundary + lineEnd);
 String connstr = null;

            connstr = "Content-Disposition: form-data; name=\"uploadedVideos\";filename=\""
                    + pathToOurFile + "\"" + lineEnd;
outputStream.writeBytes(connstr);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            buffer = new byte[bufferSize];

            // Read file
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
try {
               while (bytesRead > 0) {
                    try {
                        outputStream.write(buffer, 0, bufferSize);
                    } catch (OutOfMemoryError e) {
                        e.printStackTrace();
                        response = "outofmemoryerror";
                        return response;
                    }
                    bytesAvailable = fileInputStream.available();
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                }
            } catch (Exception e) {
                e.printStackTrace();
                response = "error";
                return response;
            }
            outputStream.writeBytes(lineEnd);
            outputStream.writeBytes(twoHyphens + boundary + twoHyphens
                    + lineEnd);
       fileInputStream.close();
        outputStream.flush();
        outputStream.close();

the server part:

HttpPostedFile file = HttpContext.Current.Request.Files[0];
string fname = Path.GetFileName(file.FileName);
   file.SaveAs(Server.MapPath(Path.Combine("~/UploadedVideos/" + Date  + "/", fname)));

please any help will be appreciated. i know i can do this using HttpClient, but its not working for me in case of large files so i want to use this way.

like image 393
Rashad.Z Avatar asked Feb 17 '15 10:02

Rashad.Z


2 Answers

Use this,

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

and here you can set File, username and password as like below using MultipartEntiry.

 private void uploadMultipartData() throws UnsupportedEncodingException {

        MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
        reqEntity.addPart("fileToUpload", new FileBody(uploadFile));
        reqEntity.addPart("uname", new StringBody("MyUserName"));
        reqEntity.addPart("pwd", new StringBody("MyPassword"));
        String response = multipost(server_url, reqEntity);

        Log.d("MainActivity", "Response :"+response);
    }

Note: You need to add httpmime jar in your libs folder.

like image 154
Krishna V Avatar answered Nov 16 '22 01:11

Krishna V


this is my working code, i recalled copying this from somewhere, cant recall it...

package my.com.myapp.utils;

import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

/**
 * This utility class provides an abstraction layer for sending multipart HTTP
 * POST requests to a web server.
 * @author www.codejava.net
 *
 */
public class MultipartUtil {
    private final String boundary;
    private static final String LINE_FEED = "\r\n";
    private HttpURLConnection httpConn;
    protected String charset;
    protected OutputStream outputStream;
    protected PrintWriter writer;
    public boolean cancel = false;
    protected boolean last_item_is_file = false;
    public static String LOG_TAG = "MultipartUtil";
    /**
     * This constructor initializes a new HTTP POST request with content type
     * is set to multipart/form-data
     * @param requestURL
     * @param charset
     * @throws IOException
     */
    public MultipartUtil(String requestURL, String charset, Boolean send_auth)
            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", "Android submit");
        //addHeaderField("lang", AppConfig.getInstance().language);
        //addHeaderField("country", AppConfig.getInstance().country);
        //User user = AppConfig.getInstance().get_user();
        /*
        if (send_auth && user != null && user.authentication_token != null && !user.authentication_token.equalsIgnoreCase("")) {
            Log.i(LOG_TAG, "user token: "+user.authentication_token);
            addHeaderField("X-User-Email", user.email);
            addHeaderField("X-User-Token", user.authentication_token);
        } else {
            Log.i(LOG_TAG, "not auth / not logged in");
        }
        */
        // httpConn.setRequestProperty("Test", "Bonjour");
    }

    public PrintWriter setup_writer() throws IOException {
        outputStream = httpConn.getOutputStream();
        writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
                true);
        return writer;
    }

    /**
     * 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();
        last_item_is_file = false;
    }

    /**
     * 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 (!cancel && (bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        outputStream.flush();
        inputStream.close();
        if (cancel) {
            writer.close();
            return;
        }

        writer.append(LINE_FEED);
        writer.flush();
        last_item_is_file = true;
    }

    public void addFileStreamPart(String fieldName, String fileName, InputStream inputStream)
            throws IOException {

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

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

        outputStream.flush();
        inputStream.close();
        if (cancel) {
            writer.close();
            return;
        }

        writer.append(LINE_FEED);
        writer.flush();
        last_item_is_file = true;
    }

    /**
     * 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) {
        httpConn.setRequestProperty(name, value);
        //writer.append(name + ": " + value).append(LINE_FEED).flush();
        //addFormField("headers["+name+"]", value);
        //writer.append(name + ": " + value).append(LINE_FEED).flush();
    }

    public HttpURLConnection finish() throws IOException {

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

        return httpConn;
    }

}
like image 1
James Tan Avatar answered Nov 16 '22 00:11

James Tan