Upload File from Android to Tomcat - java

I'm trying to receive an upload from an android device in an Apache Tomcat webserver. The code for android seems correct however I'm having issues handling the data on server side.
This is the client:
public String uploadStorageFile(String appId, String pathToFile) {
HttpURLConnection connection = null;
DataOutputStream outputStream = null;
DataInputStream inputStream = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
String storageUrl = url + "/" + appId + "/storage";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1*1024*1024;
String serverResponseMessage = null;
try
{
FileInputStream fileInputStream = new FileInputStream(new File(pathToFile) );
URL url = new URL(storageUrl);
connection = (HttpURLConnection) url.openConnection();
// Allow Inputs & Outputs
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// 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);
outputStream.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + pathToFile +"\"" + lineEnd);
outputStream.writeBytes(lineEnd);
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);
// Responses from the server (code and message)
int serverResponseCode = connection.getResponseCode();
serverResponseMessage = connection.getResponseMessage();
fileInputStream.close();
outputStream.flush();
outputStream.close();
}
catch (Exception ex)
{
//Exception handling
}
return serverResponseMessage;
}
And this is server side:
#POST
#Consumes({ MediaType.MULTIPART_FORM_DATA })
#Produces({ MediaType.APPLICATION_JSON })
public Response uploadStorageFile(#Context UriInfo ui, #Context HttpHeaders hh, #FormDataParam("file") InputStream uploadedInputStream,
#FormDataParam("filename") FormDataContentDisposition fileDetail){
String uploadedFileLocation = fileDetail.getFileName();
// save it
writeToFile(uploadedInputStream, uploadedFileLocation);
String output = "File uploaded to : " + uploadedFileLocation;
return Response.status(200).entity(output).build();
}
private void writeToFile(InputStream uploadedInputStream,
String uploadedFileLocation) {
try {
OutputStream out = new FileOutputStream(new File(
uploadedFileLocation));
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(uploadedFileLocation));
while ((read = uploadedInputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
The issue I'm facing is that fileDetail is null and so is uploadedInputStream, what am I doing wrong?
Thank you

The two file-related Objects in your uploadStorageFile method are actually bound to the same FormDataParam (i.e. - file).
Try changing your FormDataContentDisposition to the same param name as the InputStream.
EDIT: Sorry, I missed something else completely. The name of the form param you are sending is actually "uploadedFile", not file or filename. Change both of your FormDataParam's to be bound to the param named uploadedFile and they should no longer be null.

Related

Upload progress of files using HttpUrlConnection with multipart is super fast in android

I am trying to upload files using multipart with HttpUrlConnection POST method. The files are getting uploaded correctly and I am getting the response for that. But when I am tracking the progress, it just gives all the progress in 1 second even for files >100 MBs. It seems like the progress is for writing the file to buffer and not the network OutputStream. Calling flush() on the stream after writing each chunk of data doesn't help. Seems like flush just clears the stream to network and doesn't wait for the response before writing the next chunk.
Here's my code for uploading the file:
//Initialised in Constructor
boundary = twoHyphens + System.currentTimeMillis() + twoHyphens;
URL url = new URL(requestURL);
private HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setUseCaches(false);
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.setRequestMethod("POST");
httpConn.setRequestProperty("Connection", "Keep-Alive");
httpConn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + boundary);
//This method is called to upload a file
public String uploadFile(String fieldName, File uploadFile) throws IOException, InterruptedException {
String fileName = uploadFile.getName();
FileInputStream fileInputStream = new FileInputStream(uploadFile);
DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(httpConn.getOutputStream()));
dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + fieldName
+ "\"; filename=\"" + fileName + "\"" + lineEnd);
dataOutputStream.writeBytes(lineEnd);
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
//returns no. of bytes present in fileInputStream
bytesAvailable = fileInputStream.available();
bufferSize = 4096;
buffer = new byte[4096];
long size = uploadFile.length();
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
int percentage = (int) ((bytesRead / (float) size) * 100);
dataOutputStream.write(buffer, 0, bufferSize);
dataOutputStream.flush(); //doesn't help
bytesAvailable = fileInputStream.available();
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}//This finishes in 1 second
dataOutputStream.writeBytes(lineEnd);
dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
int status = httpConn.getResponseCode();
StringBuilder sb = new StringBuilder();
BufferedReader reader = null;
try {
if (status == HttpURLConnection.HTTP_OK) {
reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), "UTF-8"));
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} else {
throw new IOException("Server exception with status code: " + status);
}
} catch (Exception e) {
} finally {
if (reader != null) {
reader.close();
httpConn.disconnect();
}
}
return sb.toString();
}
Any help or explanation on this is really appreciated.
Writing to the output stream does not actually trigger the network connection. The data upload to the server is done when you call getResponseCode() , as I have detailed in my other ansswer
Only if you have some way to ask the getResponseCode() to report progress, otherwise you have no way to monitor the progress.

Send parameters while uploading file to PHP source

I'm using this class to upload image to php server from my android app.
But I want to send some parameters such as custom file name, user who uploaded the file etc.
Is there any way to send some parameters while uploading the file?
Example: name=newimage&uploadedby=username
private class UploadFileAsync extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
String sourceFileUri = "/mnt/sdcard/abc.png";
HttpURLConnection conn = null;
DataOutputStream dos = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
File sourceFile = new File(sourceFileUri);
if (sourceFile.isFile()) {
try {
String upLoadServerUri = "http://website.com/abc.php?";
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(
sourceFile);
URL url = new URL(upLoadServerUri);
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE",
"multipart/form-data");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("bill", sourceFileUri);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"bill\";filename=\""
+ sourceFileUri + "\"" + lineEnd);
dos.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math
.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0,
bufferSize);
}
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens
+ lineEnd);
serverResponseCode = conn.getResponseCode();
String serverResponseMessage = conn
.getResponseMessage();
if (serverResponseCode == 200) {
//Toast.makeText(ctx, "File Upload Complete.",
// Toast.LENGTH_SHORT).show();
}
fileInputStream.close();
dos.flush();
dos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return "Executed";
}
}
Is there any way to do this with header request, like this:
conn.setRequestProperty("parameters","name=filename&uploadedby=username");
yes it is possible
I am not a java developer but in PHP you can receive such data in 2 ways: as parameter in the URL which will be available in PHP in the $_GET array
Example, change your URL to:
String upLoadServerUri = "http://website.com/abc.php?filename=blabla&anotherparam=1234";
then in PHP: echo $_GET['filename']. $_GET is also available if you are POSTing your request.
or/and you can do this in your POST. Your POST request can contain as many extra params as you need. Here is an example how you could do this.

Problems using HttpUrlconnection to do login and upload an image

I've made an API which has an authorization part and a body part. The body part is for users to upload an image. For the basic auth part, it just need the username and the password. For the uploading part, it needs two parameters and an jpeg image file. I just got from some resources for uploading file but not combining the login part, so I modify it myself, but I don't know what's wrong in my code, it doesn't work. The following is my code:
public String multipartRequest(String urlTo, Map<String, String> parmas, String filepath, String filefield, String fileMimeType) throws CustomException {
HttpsURLConnection 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 = (HttpsURLConnection) url.openConnection();
///// certification
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
SSLSocketFactory newFactory = sc.getSocketFactory();
connection.setSSLSocketFactory(newFactory);
connection.setHostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
String a = username + ":" + password;
byte[] data = a.getBytes();
String info = "Basic " + Base64.encodeToString(data, Base64.DEFAULT);
connection.setRequestProperty("Authorization", info);
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Content-Type", "text/plain");
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);
inputStream = connection.getInputStream();
result = this.convertStreamToString(inputStream);
fileInputStream.close();
inputStream.close();
outputStream.flush();
outputStream.close();
return result;
} catch (Exception e) {
throw new CustomException("error 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();
}
I don't know why it doesn't work.
Does anyone know how to use httpurlconnection to do both login and uploading files? In my code, I add both the following lines, is this a problem? I mean use "Content-Type" for multiple times(Login and Uploading files):
For Login part:
connection.setRequestProperty("Content-Type", "text/plain");
For uploading file part:
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
But I call them at the same time(same function), is this a problem?

How do I put HttpURLConnection into BroadcastReceiver OnReceive()?

I have an HttpURLConnection uploading a file, and my server then emails it. It works great. However, I don't want it in an Activity, I want it in the SMS receiver OnRecieve(), yet I can't seem to get it to work.
Please help? When I put the code into OnReceive(), it simply fails:(
Here's my code, it's quite simple:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
try{
int serverResponseCode = 0;
final String upLoadServerUri = "http://MY_URL_EXAMPLE/upload_file_functions.php";
String fileName = "/mnt/sdcard/MyFile.dat";
HttpURLConnection conn = null;
DataOutputStream dos = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
File sourceFile = new File("/mnt/sdcard/MyFile.dat");
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL(upLoadServerUri);
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\""+ fileName + "\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
String serverResponseMessage = conn.getResponseMessage();
Log.i("uploadFile", "HTTP Response is : "
+ serverResponseMessage + ": " + serverResponseCode);
if(serverResponseCode == 200){
// it worked !
}
//close the streams //
fileInputStream.close();
dos.flush();
dos.close();
}catch (Exception e){
}
Bunch of F%$kn losers on here sometimes, I must say. I'll go ahead and answer my OWN question again:
You cannot do an httpURLrequest in BroadcastReceiver(). It must be done in a service:
public class UploadService extends IntentService
{
public UploadService()
{
super("UploadService");
}
#Override
protected void onHandleIntent(Intent intent)
{
public void postForm(String phn, String mssg)
{
try{
int serverResponseCode = 0;
final String upLoadServerUri = "http://MY_URL_EXAMPLE/upload_file_functions.php";
String fileName = "/mnt/sdcard/MyFile.dat";
HttpURLConnection conn = null;
DataOutputStream dos = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
File sourceFile = new File("/mnt/sdcard/MyFile.dat");
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL(upLoadServerUri);
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\""+ fileName + "\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
String serverResponseMessage = conn.getResponseMessage();
Log.i("uploadFile", "HTTP Response is : "
+ serverResponseMessage + ": " + serverResponseCode);
if(serverResponseCode == 200){
// it worked !
}
//close the streams //
fileInputStream.close();
dos.flush();
dos.close();
}catch (Exception e){
}
}
}
Called with:
context.startService(new Intent(context, UploadService.class));

Upload file into XAMPP Server using HttpURLConnection

I am trying to upload file into XAMPP server but I could not see any file into server project folder.But I see byte writing completed.What is the problem in my code.Please help me anybody.
Sample code::
import java.io.*;
import java.net.*;
public class ServletCom {
public static void main(String[] args)
throws Exception
{
HttpURLConnection conn = null;
BufferedReader br = null;
DataOutputStream dos = null;
DataInputStream inStream = null;
InputStream is = null;
OutputStream os = null;
boolean ret = false;
String StrMessage = "";
String exsistingFileName = "C:\\Users\\hossain\\Desktop\\photo\\image\\text.txt";
String fileName="text.txt";
String lineEnd = "";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1*1024*1024;
String responseFromServer = "";
String urlString = "http://local.ebajar/";
try
{
//------------------ CLIENT REQUEST
FileInputStream fileInputStream = new FileInputStream( new File(exsistingFileName) );
// open a URL connection to the Servlet
URL url = new URL(urlString);
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
// Allow Inputs
conn.setDoInput(true);
// Allow Outputs
conn.setDoOutput(true);
// Don't use a cached copy.
conn.setUseCaches(false);
// Use a post method.
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
dos = new DataOutputStream( conn.getOutputStream() );
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"" + fileName + "\"" + lineEnd);
//dos.writeBytes("Content-Disposition: form-data; name="upload";"+ " filename="" + exsistingFileName +""" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
System.out.println("write complete........" );
// close streams
fileInputStream.close();
dos.flush();
dos.close();
}
catch (MalformedURLException ex)
{
System.out.println("From ServletCom CLIENT REQUEST:"+ex);
}
catch (IOException ioe)
{
System.out.println("From ServletCom CLIENT REQUEST:"+ioe);
}
catch (Exception e)
{
System.out.println("From ServletCom CLIENT REQUEST:"+e);
}
}
}

Categories

Resources