I need to upload Arraylist
of images to the server without using any library. I am using Asynctask
to upload single image and it's working perfectly with the help of httpurlconnection multipart/form-data. Now i need to change my code to upload multiple files of any type by using Arraylist<String>
but my problem is the existing code's FileinputStream
don't support arraylist and i don't have idea what to use instead of Fileinputstream
to upload arraylist to server and i don't want to use any library for this either.
public class multipart_test extends AsyncTask<Void,Void,String> {
Context context;
String Images;
public static final String TAG = "###Image Uploading###";
public multipart_test(Context context,String Upload_Images) {
this.context = context;
this.Images = Upload_Images;
}
@Override
protected String doInBackground(Void... params) {
BufferedReader reader;
String WebPath = null;
try {
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1024 * 1024;
//todo change URL as per client ( MOST IMPORTANT )
URL url = new URL("10.0.0.1/uploadMultipart.php");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Allow Inputs & Outputs.
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// Set HTTP method to POST.
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
FileInputStream fileInputStream;
DataOutputStream outputStream;
outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"reference\""+ lineEnd);
outputStream.writeBytes(lineEnd);
//outputStream.writeBytes("my_refrence_text");
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"uploadFile\";filename=\"" + "profileImage" +"\"" + lineEnd);
outputStream.writeBytes(lineEnd);
//Dummy ArrayList for upload
ArrayList<String> uploadFiles = new ArrayList<>();
uploadFiles.add(Images);
uploadFiles.add(Images);
uploadFiles.add(Images);
uploadFiles.add(Images);
fileInputStream = new FileInputStream(uploadFiles); // NOT SUPPORTING ARRAYLIST HERE
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
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);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
fileInputStream.close();
}
// Responses from the server (code and message)
int serverResponseCode = connection.getResponseCode();
String result = null;
if (serverResponseCode == 200) {
StringBuilder s_buffer = new StringBuilder();
InputStream is = new BufferedInputStream(connection.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = br.readLine()) != null) {
s_buffer.append(inputLine);
}
result = s_buffer.toString();
}
connection.getInputStream().close();
outputStream.flush();
outputStream.close();
if (result != null) {
Log.d("result_for upload", result);
}
return WebPath;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
I also tried to put FileInputStream
into loop but uploading images into multiple request is not what i want. My server require's app to make single request for n number of images. Any help would be appreciate but without use of any library
NOTE that I have not tried if this code acctually works with the HttpURLConnection but it should.
From what I've read from the internet you can still use that loop you mentioned but with some modifications.
I followed the tutorial on multipart/form-data here dev.to, to make this more of a learning post I'll tell you what this method is what should happen.
The multipart/form-data is sent like this
--boundary
Content-Disposition: form-data; name="something1"
data1
--boundary
Content-Disposition: form-data; name="something2"
data2
--boundary--
What I would do is to create a new method but you can just write the code in your already existing method.
public byte[] get_multipart_data(List<String> files, String boundary)
You want to write is the boundary followed by the disposition and then the data. Do that for all the files and then you send the closing boundary. This will generate the multipart/form-data structure that you want.
In psudo-code this would be
loop for all files
write "--boundary"
write "Content-Disposition: ...."
write image_data
end
write "--boundary--"
The code could be written like this, first you define your variables
ByteArrayOutputStream message = null;
DataOutputStream stream = null;
FileInputStream fileInputStream;
int maxBufferSize = 1024 * 1024;
byte[] buffer = new byte[maxBufferSize];
byte[] sendData = new byte[0];
Here is where the data will get generated. It starts with concatenating the boundary and then reading the data. That data is written to the stream and you continue the loop for all files/images.
try {
message = new ByteArrayOutputStream();
stream = new DataOutputStream(message);
// Loop though all file names
for(String fileName : files) {
stream.writeBytes("--" + boundary + "\r\n"); // Start boundary
stream.writeBytes("Content-Disposition: form-data; name=\"" + fileName + "\"\r\n\r\n");
// Read the image data
fileInputStream = new FileInputStream(fileName);
int readBytes = 0;
while((readBytes = fileInputStream.read(buffer)) != -1) {
// Write file data to output
stream.write(buffer, 0, readBytes);
}
fileInputStream.close();
stream.writeBytes("\r\n");
}
stream.writeBytes("--" + boundary + "--\r\n"); // Closing boundary
sendData = message.toByteArray();
} catch(IOException e) {
e.printStackTrace();
}
Now the byte array sendData
will contain the multipart/form-data that you need to send with your HttpURLConnection.
I've not been that active here for a long time. Tell me if you need some more specification or that I clarify my text :D
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With