Sending files using POST with HttpURLConnection
I have no idea why the HttpURLConnection
class does not provide any means to send files without having to compose the file wrapper manually. Here's what I ended up doing, but if someone knows a better solution, please let me know.
Input data:
Bitmap bitmap = myView.getBitmap();
Static stuff:
String attachmentName = "bitmap";
String attachmentFileName = "bitmap.bmp";
String crlf = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
Setup the request:
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);
Start content wrapper:
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);
Convert Bitmap
to 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);
End content wrapper:
request.writeBytes(this.crlf);
request.writeBytes(this.twoHyphens + this.boundary +
this.twoHyphens + this.crlf);
Flush output buffer:
request.flush();
request.close();
Get response:
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();
Close response stream:
responseStream.close();
Close the connection:
httpUrlConnection.disconnect();
PS: Of course I had to wrap the request in private class AsyncUploadBitmaps extends AsyncTask<Bitmap, Void, String>
, in order to make the Android platform happy, because it doesn't like to have network requests on the main thread.
POST a file with other form data using HttpURLConnection
Android multipart upload.
public String multipartRequest(String urlTo, Map<String, String> parmas, String filepath, String filefield, String fileMimeType) throws CustomException {
HttpURLConnection connection = null;
DataOutputStream outputStream = null;
InputStream inputStream = null;
String twoHyphens = "--";
String boundary = "*****" + Long.toString(System.currentTimeMillis()) + "*****";
String lineEnd = "\r\n";
String result = "";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
String[] q = filepath.split("/");
int idx = q.length - 1;
try {
File file = new File(filepath);
FileInputStream fileInputStream = new FileInputStream(file);
URL url = new URL(urlTo);
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("User-Agent", "Android Multipart HTTP Client 1.0");
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"" + filefield + "\"; filename=\"" + q[idx] + "\"" + lineEnd);
outputStream.writeBytes("Content-Type: " + fileMimeType + lineEnd);
outputStream.writeBytes("Content-Transfer-Encoding: binary" + lineEnd);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(lineEnd);
// Upload POST Data
Iterator<String> keys = parmas.keySet().iterator();
while (keys.hasNext()) {
String key = keys.next();
String value = parmas.get(key);
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"" + key + "\"" + lineEnd);
outputStream.writeBytes("Content-Type: text/plain" + lineEnd);
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(value);
outputStream.writeBytes(lineEnd);
}
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
if (200 != connection.getResponseCode()) {
throw new CustomException("Failed to upload code:" + connection.getResponseCode() + " " + connection.getResponseMessage());
}
inputStream = connection.getInputStream();
result = this.convertStreamToString(inputStream);
fileInputStream.close();
inputStream.close();
outputStream.flush();
outputStream.close();
return result;
} catch (Exception e) {
logger.error(e);
throw new CustomException(e);
}
}
private String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
Calling code:
//setup params
Map<String, String> params = new HashMap<String, String>(2);
params.put("foo", hash);
params.put("bar", caption);
String result = multipartRequest(URL_UPLOAD_VIDEO, params, pathToVideoFile, "video", "video/mp4");
//next parse result string
Ref Link https://stackoverflow.com/a/26145565/1143026
Passing parameters with HttpURLConnection when Uploading audio file
Refer the below URL it ha clear answer to pass the parameters
Sending files using POST with HttpURLConnection
Related Topics
Imageview of Png Doesn't Appear (Maybe It's Too Big)
Google Maps, No Option for Starting the Navigation, Only Preview Is There
Illegalstateexception: Link Does Not Have a Navcontroller Set
Convert File: Uri to File in Android
How to Delete Shared Preferences Data from App in Android
How to Dynamically Hide a Menu Item in Bottomnavigationview
How to Clear Navigation Stack After Navigating to Another Fragment in Android
How to Disable Cache in Android Webview
Admob Ads Not Loading - Failed to Load Ad: 0
Not Opening Specific Activity on Notification Click When the App Is in Background/Not Running
Android Compress Video Before Upload to Server
How to Make a Background 20% Transparent on Android
Change Button Background At Runtime in Android
Load Video from Firebase Storage to Videoview
Image Scale Type Center Crop on Flutter
How Listview'S Recycling Mechanism Works
How to Get Screen Dimensions as Pixels in Android
How to Handle Notification When App in Background in Firebase