Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

simple HttpURLConnection POST file multipart/form-data from android to google blobstore

I have very little idea how html works.What i want to do is exactly similar to the following but on android

<body>      <form action="<%= some_url %>" method="post" enctype="multipart/form-data">          <input type="file" name="myFile">          <input type="submit" value="Submit">      </form>  </body>

I tried the following code -

private static void postToUrl(String url_to_upload_on,         String file_name_with_ext, byte[] byteArray) {      String attachmentName = "file";     String attachmentFileName = file_name_with_ext;     String crlf = "\r\n";     String twoHyphens = "--";     String boundary =  "*****";      try{      URL url = new URL(url_to_upload_on);     HttpURLConnection connection = (HttpURLConnection) url.openConnection();     connection.setDoOutput(true);     connection.setRequestMethod("POST");      connection.setRequestProperty(         "Content-Type", "multipart/form-data;boundary=" + boundary);     DataOutputStream request = new DataOutputStream(             connection.getOutputStream());      request.writeBytes(twoHyphens + boundary + crlf);     request.writeBytes("Content-Disposition: form-data; name=\"" +         attachmentName + "\";filename=\"" +          attachmentFileName + "\"" + crlf);     request.writeBytes(crlf);     request.write(byteArray);     request.writeBytes(crlf);     request.writeBytes(twoHyphens + boundary +          twoHyphens + crlf);     request.flush();     request.close();      }catch(Exception e){         e.printStackTrace();     }   } 

this gives me no direct errors but when i get error-stream using-

 Log.w(TAG, "connection.getErrorStream() = " +      connection.getErrorStream()); 

i get this-

12-14 18:25:54.911: W/uploadToBlobStore(30558): httpUrlConnection.getErrorStream() = com.android.okhttp.internal.http.HttpTransport$FixedLengthInputStream@426dd5a8 

with no success.

PS- I am uploading a file to google blobstore

PS- I can not use Apache http libraries or its multipart class as android says its depreciated

EDIT 1

Now I am using the following code but it is working only for files less then 2.3Mb -

private static void postToUrl3(String url_to_upload_on,         String file_name_with_ext, byte[] byteArray, String mimeType) {      CloseableHttpClient httpClient = null;      try {          httpClient = HttpClientBuilder.create().build();          HttpPost postRequest = new HttpPost(url_to_upload_on);           MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();         reqEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);                     ByteArrayBody bab = new ByteArrayBody(byteArray, file_name_with_ext);                    reqEntity.addPart("file", bab);                  postRequest.setEntity(reqEntity.build());           httpClient.execute(postRequest);// takes time      } catch (Exception e) {         Log.w("uploadToBlobStore", "postToUrl Exception e = " + e);         e.printStackTrace();     } finally {         if (httpClient != null) {             Log.w("uploadToBlobStore", "connection.closing ");             try {                 httpClient.close();             } catch (IOException e) {                 Log.w("uploadToBlobStore", "connection.closing errot e = "                         + e);                 e.printStackTrace();             }         }     } } 

how to make it work with larger files?

PS- i am sending it to blobstore and i did set the maxUploadSizeBytesand MaxUploadSizeBytesPerBlob to 30MB.I am not able to figure out the issue with size because google blobstore documentation says -

Google App Engine includes the Blobstore service, which allows applications to serve data objects limited only by the amount of data that can be uploaded or downloaded over a single HTTP connection.

So can it be a problem with http connection? and if so, how can i configure it.

like image 480
Flying Monkey Avatar asked Dec 14 '15 20:12

Flying Monkey


1 Answers

I am using HttpURLConnection to achieve this.

Create one Multipart custom class ::

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

Use it (async way) ::

    MultipartUtility multipart = new MultipartUtility(requestURL, charset);      // In your case you are not adding form data so ignore this                 /*This is to add parameter values */                 for (int i = 0; i < myFormDataArray.size(); i++) {                     multipart.addFormField(myFormDataArray.get(i).getParamName(),                             myFormDataArray.get(i).getParamValue());                 }   //add your file here.                 /*This is to add file content*/                 for (int i = 0; i < myFileArray.size(); i++) {                     multipart.addFilePart(myFileArray.getParamName(),                             new File(myFileArray.getFileName()));                 }                  List<String> response = multipart.finish();                 Debug.e(TAG, "SERVER REPLIED:");                 for (String line : response) {                     Debug.e(TAG, "Upload Files Response:::" + line); // get your server response here.                     responseString = line;                 } 
like image 199
KDeogharkar Avatar answered Sep 18 '22 16:09

KDeogharkar