How to retrieve multipart/form-data from HttpServletRequest in Struts2 - java

I am trying to retrieve the sent data on post request from the client android app, but unfortunately i am not getting multipart data from request, the code just returns null value.
Client side code: option 1:
private String uploadFile(String filePath) {
Log.d(TAG, "uploadFile: called");
HttpURLConnection connection;
DataOutputStream dos = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1024 * 1024;
File uploadFile = new File(filePath);
if(!uploadFile.isFile()) {
mDownloadStatus = DownloadStatus.NOT_INITIALIZED;
Log.d(TAG, "uploadFile: file not found");
return null;
}
try {
FileInputStream fileInputStream = new FileInputStream(uploadFile);
mDownloadStatus = DownloadStatus.PROCESSING;
URL url = new URL(POSTUPLOADFILE_URL);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setReadTimeout(10000);
connection.setConnectTimeout(15000);
connection.setRequestProperty("ENCTYPE", "multipart/form-data");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
connection.setRequestProperty("uploaded_file", filePath);
connection.connect();
dos = new DataOutputStream(connection.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""+ filePath + "\"" + lineEnd);
dos.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
Log.d(TAG, "uploadFile: bytesAvailable: " + bytesAvailable);
Log.d(TAG, "uploadFile: initial available: " + bytesAvailable);
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
Log.d(TAG, "uploadFile: initial: " + bytesRead);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
Log.d(TAG, "uploadFile: bytesRead: " + bytesRead);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
int responseCode = connection.getResponseCode();
Log.d(TAG, "uploadFile: respnse code: " + responseCode);
fileInputStream.close();
dos.flush();
dos.close();
// receive upload link from server
int ch;
StringBuilder sb = new StringBuilder();
InputStream is = connection.getInputStream();
while ((ch = is.read()) != -1) {
sb.append((char)ch);
}
is.close();
mDownloadStatus = DownloadStatus.OK;
return sb.toString();
} catch (IOException e) {
Log.e(TAG, "uploadFile: IOException: " + e);
}
mDownloadStatus = DownloadStatus.FAILED_OR_EMPTY;
return null;
}
client side code: option 2:
private String uploadFile(String filePath) {
File uploadFile = new File(filePath);
if(!uploadFile.isFile()) {
mDownloadStatus = DownloadStatus.NOT_INITIALIZED;
Log.d(TAG, "uploadFile: file not found");
return null;
}
try {
mDownloadStatus = DownloadStatus.PROCESSING;
HttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost(POSTUPLOADFILE_URL);
FileBody fileBody = new FileBody(new File(filePath));
StringBody title = new StringBody("Filename: " + filePath, ContentType.DEFAULT_TEXT);
StringBody description = new StringBody("This is a post file", ContentType.DEFAULT_TEXT);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addPart("file", fileBody);
builder.addPart("title", title);
builder.addPart("description", description);
HttpEntity entity = builder.build();
post.setEntity(entity);
Log.d(TAG, "uploadFile: executing request: ");
HttpResponse response = httpClient.execute(post);
Log.d(TAG, "uploadFile: response status: " + response.getCode());
Log.d(TAG, "uploadFile: " + response.toString());
} catch (IOException e) {
Log.e(TAG, "uploadFile: IOException" + e.getMessage(), e);
}
mDownloadStatus = DownloadStatus.FAILED_OR_EMPTY;
return null;
}
Server side code:
public String uploadFile() throws IOException, ServletException, FileUploadException {
System.out.println("upload file on postAction: called");
HttpServletRequest request = ServletActionContext.getRequest();
List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
System.out.println("items size: " + items.size());
for(FileItem item: items) {
if(item.isFormField()) {
// get file
} else {
}
}
return null;
}
PROBLEM: there is multipart data on the request,because request.contentLength is reasonable size, but list size just returns 0, so now I can't get uploaded file. How can I solve to get multipart data from the request?

I figured out the solution for the problem by using 'MultipartRequestWrapper'
public String uploadFile() throws IOException, ServletException, FileUploadException {
System.out.println("upload file on postAction: called");
HttpServletRequest request = ServletActionContext.getRequest();
MultiPartRequestWrapper multipartRequest = ((MultiPartRequestWrapper)ServletActionContext.getRequest());
Enumeration<String> fileParameterNames = multipartRequest.getFileParameterNames();
if(fileParameterNames.hasMoreElements()) {
String inputValue = fileParameterNames.nextElement();
System.out.println("inputValue: " + inputValue);
String[] localFileNames = multipartRequest.getFileNames(inputValue);
for (String fn : localFileNames) {
System.out.println("local filename = " + fn);
}
File[] files = multipartRequest.getFiles(inputValue);
for (File cf : files) {
File destFile = new File(POST_FILE_DESTINATION + localFileNames[0]);
FileUtils.copyFile(cf, destFile);
FileUtils.deleteQuietly(cf);
}
}
return null
}
the reference here

Related

java.io.FileNotFoundException: /storage/emulated/0/Download/smiley.csv: open failed: EACCES (Permission denied)

I am uploading a file to my php webserver, but however I'm getting the permission denied. It works for mp3 and image extensions. However for .csv, i'll get that error when i hit upload. I'm new to this and I can't figure out if its the permission issue on android or the upload doesn't support uploading of csv. Appreciate any guidance or help. Thanks!
My upload code:
private class UploadFileAsync extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
String sourceFileUri = "/storage/emulated/0/Download/smiley.csv";
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);
Log.d("myTag", ""+sourceFile.isFile());
if (sourceFile.isFile()) {
try {
String upLoadServerUri = "https://www.mywebsite.tk/upload.php?";
// 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("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);
// 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();
if (serverResponseCode == 200) {
// messageText.setText(msg);
//Toast.makeText(ctx, "File Upload Complete.",
// Toast.LENGTH_SHORT).show();
// recursiveDelete(mDirectory1);
}
// close the streams //
fileInputStream.close();
dos.flush();
dos.close();
} catch (Exception e) {
// dialog.dismiss();
e.printStackTrace();
}
// dialog.dismiss();
} // End else block
} catch (Exception ex) {
// dialog.dismiss();
ex.printStackTrace();
}
Log.d("myTag", "I iz completed");
return "Executed";
}
}
My PHP Server Code
<?php
if (is_uploaded_file($_FILES['bill']['tmp_name'])) {
$uploads_dir = './';
$tmp_name = $_FILES['bill']['tmp_name'];
$pic_name = $_FILES['bill']['name'];
move_uploaded_file($tmp_name, $uploads_dir.$pic_name);
}
else{
echo "File not uploaded successfully.";
}
?>
If you wanna get a file from android, use File constructor with path and file.
e.g.
new File(path, file);
My project: check File#getFile(Context context, String fileName)

How can I send multiple files and texts simultaneously to server over http protocol in Android?

I wanna send a file and some variables to server, to insert in a table in a android app using AsyncTask. here is my java code:
try {
URL url = new URL(upLoadServerUri);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setUseCaches(false);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,"UTF-8"));
String post_data= URLEncoder.encode("username" , "UTF-8")+"="+URLEncoder.encode(username,"UTF-8");
bufferedWriter.write(post_data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
result="";
String line="";
while ((line=bufferedReader.readLine()) != null){
result += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
}catch (MalformedURLException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
try {
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("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);
// 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();
// close the streams //
fileInputStream.close();
dos.flush();
dos.close();
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
And PHP code:
if (is_uploaded_file($_FILES['bill']['tmp_name'])) {
$uploads_dir = './sensorLog/$user_name';
$tmp_name = $_FILES['bill']['tmp_name'];
$pic_name = $_FILES['bill']['name'];
move_uploaded_file($tmp_name, $uploads_dir.$pic_name);
if($conn->query($mysql_qry) === TRUE) {
echo "upload and update successful";
}else { echo "Error" . $mysql_qry . "<br>" . $conn->error;}
}else{ echo "File not uploaded successfully."; }
I use two httpconnection object and I think this is the problem. How can I send variables and file simultaneously? this code upload the file to server, but the table isn't updated. it just add an empty row:(.
Use this class to send multipart requests:
class MultipartUtility {
public HttpURLConnection httpConn;
public OutputStream request;//if you wanna send anything out of ordinary use this;
private final String boundary = "*****";//alter this as you wish
private final String crlf = "\r\n";
private final String twoHyphens = "--";
public MultipartUtility(String requestURL)
throws IOException {
URL url = new URL(requestURL);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setUseCaches(false);
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
httpConn.setRequestMethod("POST");
//alter this part if you wanna set any headers or something
httpConn.setRequestProperty("Connection", "Keep-Alive");
httpConn.setRequestProperty("Cache-Control", "no-cache");
httpConn.setRequestProperty(
"Content-Type", "multipart/form-data;boundary=" + this.boundary);
request = httpConn.getOutputStream();
}
//or add some other constructor to better fit your needs; like set cookies and stuff
public void addFormField(String name, String value)throws IOException {
request.write(( this.twoHyphens + this.boundary + this.crlf).getBytes());
request.write(("Content-Disposition: form-data; name=\"" + name + "\""+ this.crlf).getBytes());
request.write(this.crlf.getBytes());
request.write((value).getBytes());
request.write(this.crlf.getBytes());
request.flush();
}
public void addFilePart(String fieldName, File uploadFile)
throws IOException,Exception {
if(uploadFile.isDirectory())throw new Exception("for real? what do you expect to happen?");
request.write((this.twoHyphens + this.boundary + this.crlf).getBytes());
request.write(("Content-Disposition: form-data; name=\"" +
fieldName + "\";filename=\"" +
uploadFile.getName()+ "\"" + this.crlf).getBytes());
request.write(this.crlf.getBytes());
InputStream is=new FileInputStream(uploadFile);
byte[] bytes = new byte[1024];
int c=is.read(bytes);
while(c>0){
request.write(bytes,0,c);
c=is.read(bytes);
}
request.write(this.crlf.getBytes());
request.flush();
is.close();
}
public String finish() throws IOException {
String response ="";
request.write((this.twoHyphens + this.boundary +
this.twoHyphens + this.crlf).getBytes());
request.flush();
request.close();
int status = httpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
InputStream responseStream = httpConn.getInputStream();
byte[] b=new byte[1024];
int c=responseStream.read(b);
while(c>0){
response=response+new String(b,0,c);
c=responseStream.read(b);
}
responseStream.close();
} else {
httpConn.disconnect();
throw new IOException("Server returned non-OK status: " + status);
}
httpConn.disconnect();
return response;
}
public InputStream finish_with_inputstream()throws Exception{
request.write((this.twoHyphens + this.boundary +
this.twoHyphens + this.crlf).getBytes());
request.flush();
request.close();
int status = httpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
return httpConn.getInputStream();
} else {
throw new IOException("Server returned non-OK status: " + status);
}
}
}
example:
try{
MultipartUtility m=new MultipartUtility("https://mydomain");//now add you different data parts;
m.addFilePart("file_part",new File("some_file_location"));
m.addFormField("value_name","value");
//call either of the below methods based on what you need; do not call both!
String result=m.finish();//call this if the response is a small text
InputStream is=m.finish_with_inputstream(); //call this if the response is huge and not fitting in memory; don't forget to disconnect the connection afterwards;
} catch (IOException e) {
e.printStackTrace();
}
now you can handle all these data in one request on the php side:
$value=$_POST["value_name"];
$file_data=file_get_contents($_FILES["file_part"]["tmp_name"])
so for you situation it would be like below:
try{
MultipartUtility m=new MultipartUtility("https://mydomain");
m.addFilePart("bill",new File(sourceFile));
m.addFormField(URLEncoder.encode("username" , "UTF-8"),URLEncoder.encode(username,"UTF-8"));
String result=m.finish();
} catch (Exception e) {
e.printStackTrace();
}

Unable to upload file from android app to Flask Server but working when uploaded from Web UI

I am attempting to upload a file from my Android app to the Flask server. The logcat on Android Studio shows I/uploadFile: HTTP Response is : OK: 200 but I am unable to see the uploaded file on the server.
Following is my flask code which I have referred to from http://flask.pocoo.org/docs/0.12/patterns/fileuploads/:
import os
from flask import Flask, request, redirect, url_for, jsonify
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = '/Users/Vishwak/PycharmProjects/BraiNet/'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
print request
print request.values
# check if the post request has the file part
if 'file' not in request.files:
# flash('No file part')
return redirect(request.url)
print(request.files['file'])
file = request.files['file']
# if user does not select file, browser also
# submit a empty part without filename
if file.filename == '':
print(file)
# flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
print(file)
print(file.filename)
filename = secure_filename(file.filename)
# print filename
print(app.config['UPLOAD_FOLDER'])
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('upload_file',
filename=filename))
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form method=post enctype=multipart/form-data>
<p><input type=file name=file>
<input type=submit value=Upload>
</form>
'''
if __name__ == '__main__':
app.run()
This works as expected when I upload a file using the Web interface and I can view the file on the server.
The problem arises when I try to upload the file from the Android app. Here is the java code:
private class UploadTask extends AsyncTask {
private Context context;
public UploadTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(String... params) {
String fileName =path;
String fileName2=path.substring(path.lastIndexOf("/")+1);
String fileName4 = fileName2.substring(0, fileName2.lastIndexOf("."));
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(fileName);
if (!sourceFile.isFile()) {
Log.e("uploadFile", "Source File not exist :"
+ uri);
runOnUiThread(new Runnable() {
public void run() {
// messageText.setText("Source File not exist :"
// +uploadFilePath + "" + uploadFileName);
}
});
} else {
try {
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(sourceFile);
// System.out.println(Array.toString(fileInputStream));
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); // Dont 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("uploaded_file", fileName);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; uploaded_file=uploaded_file ;filename=" + fileName + lineEnd);
// dos.writeBytes("Content-Disposition: form-data; name=" + fileName4 + ";filename=" + fileName2 + "" + 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) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this, "File Upload Complete.",
Toast.LENGTH_SHORT).show();
}
});
}
//close the streams //
fileInputStream.close();
dos.flush();
dos.close();
}
catch (MalformedURLException ex) {
ex.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
// messageText.setText("MalformedURLException Exception : check script url.");
Toast.makeText(MainActivity.this, "MalformedURLException",
Toast.LENGTH_SHORT).show();
}
});
Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
}
catch (Exception e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
// messageText.setText("Got Exception : see logcat ");
Toast.makeText(MainActivity.this, "Got Exception : see logcat ",
Toast.LENGTH_SHORT).show();
}
});
Log.e("Upload Exception", "Exception:" + e.getMessage(), e);
}
}
return null;
} // End else block
I am a novice at Java and I don't really understand where I am going wrong in my Android code and what I will have to change to make this work.
Any feedback on changing the Flask or Android code will be greatly appreciated.

How can I receive a mp3 file from client App android to play framework?

I'm trying to make an application that sends an mp3 file to a server and save it in disk. But I'm having trouble finding information on how to do this, I just found this client code and now I need to implement the server, I need to use the Play Framework to do the web service, can anyone give me a help in how to do this.
My client:
public class Client extends AsyncTask<Void, Void, Void> {
private static final int BUFFER_SIZE = 1 * 1024 * 1024;
private String SongPath;
#Override
protected Void doInBackground(Void... params) {
HttpURLConnection connection = null;
DataOutputStream dos = null;
DataInputStream inStream = null;
String existingFileName = SongPath;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
String responseFromServer = "";
String urlString = "http://177.105.46.89:9000/uploadSong";
try {
//------------------ CLIENT REQUEST
FileInputStream fileInputStream = new FileInputStream(new File(existingFileName));
// open a URL connection to the Servlet
URL url = new URL(urlString);
// Open a HTTP connection to the URL
connection = (HttpURLConnection) url.openConnection();
// Allow Inputs
connection.setDoInput(true);
// Allow Outputs
connection.setDoOutput(true);
// Don't use a cached copy.
connection.setUseCaches(false);
// Use a post method.
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
dos = new DataOutputStream(connection.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
// dos.writeBytes("Content-Disposition: form-data; name=song" + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + existingFileName + "\"" + 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);
// close streams
Log.e("Debug", "File is written");
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
Log.e("Debug", "error: " + ex.getMessage(), ex);
} catch (IOException ioe) {
Log.e("Debug", "error: " + ioe.getMessage(), ioe);
}
//------------------ read the SERVER RESPONSE
try {
inStream = new DataInputStream(connection.getInputStream());
String str;
while ((str = inStream.readLine()) != null) {
Log.e("Debug", "Server Response " + str);
}
inStream.close();
} catch (IOException ioex) {
Log.e("Debug", "error: " + ioex.getMessage(), ioex);
}
return null;
}
public String getSongPath() {
return SongPath;
}
public void setSongPath(String songPath) {
SongPath = songPath;
}
}

Posting a multipart request with image in Android?

I am trying to post a JSON representation of my object and an optional image to my Spring backend. However, I am having major trouble posting a request with an image. I have managed to post the first part to the server; the JSON object. However when I try to add a second part which is an image captured by the user nothing happens. I don't see any stacktraces.
What am I doing wrong and how do I post an image along the request. This is what I have...
String boundary = UUID.randomUUID().toString();
String twoHyphens = "--";
String attachmentName = "data";
String crlf = "\r\n";
try {
URI uri = new URI("http://myappserver.com/app");
HttpURLConnection urlConnection = (HttpURLConnection) uri.toURL().openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Connection", "Keep-Alive");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
DataOutputStream dos = new DataOutputStream(urlConnection.getOutputStream());
InputStream inputStream = context.getContentResolver().openInputStream(question.getUri());
// FIRST PART; A JSON object
dos.writeBytes(twoHyphens + boundary);
dos.writeBytes(crlf);
dos.writeBytes("Content-Type: application/json");
dos.writeBytes(crlf);
dos.writeBytes("Content-Disposition: form-data; name=\"data\"");
dos.writeBytes(crlf);
dos.writeBytes(crlf);
dos.writeBytes(jsonEntity);
dos.writeBytes(crlf);
// SECOND PART; A image..
dos.writeBytes(twoHyphens + boundary);
dos.writeBytes(crlf);
dos.writeBytes("Content-Type: image/jpg");
dos.writeBytes(crlf);
dos.writeBytes("Content-Disposition: form-data; name=\"image\"");
dos.writeBytes(crlf);
dos.writeBytes(crlf);
// Something must be done here. I guess I must encode it to Base64 here.
// How can I avoid loading the whole image at once so I don't get out of memory errors.
dos.writeBytes(crlf);
dos.writeBytes(twoHyphens + boundary + twoHyphens + crlf);
dos.close();
} catch (Exception e) {
}
The code illustrates how to send a file (here it is pdf). Go through it, it will be helpful for you to debug your code.
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
FileInputStream fileInputStream = new FileInputStream(file);
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"attachment_0\";filename=\"" + file.getName() + "\"" + lineEnd);
dos.writeBytes("Content-Type: text/pdf" + lineEnd);
dos.writeBytes("Content-Length: " + file.length() + 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 + lineEnd);
fileInputStream.close();
}
//for sending a parameter, see below, key is the key of the webservice parameter.
dos.writeBytes("Content-Disposition: form-data; name=\""+key+"\"" + lineEnd);
dos.writeBytes(lineEnd);
dos.writeBytes(requestData.get(key).toString() + lineEnd);
Below is my implementation of a MULTIPART form data upload using HttpURLConnection class. This class employs a Dynamic usage so that multiple request can be invoked at a time with different sets of data.
NB: I'm breaking the json part into individual text forms inorder to maintain consistency with my server. You may modify it to match your servers requirement.
public class WebConnector {
String boundary = "-------------" + System.currentTimeMillis();
private static final String LINE_FEED = "\r\n";
private static final String TWO_HYPHENS = "--";
private StringBuilder url;
private String protocol;
private HashMap<String, String> params;
private JSONObject postData;
private List<String> fileList;
private int count = 0;
private DataOutputStream dos;
public WebConnector(StringBuilder url, String protocol,
HashMap<String, String> params, JSONObject postData) {
super();
this.url = url;
this.protocol = protocol;
this.params = params;
this.postData = postData;
createServiceUrl();
}
public WebConnector(StringBuilder url, String protocol,
HashMap<String, String> params, JSONObject postData, List<String> fileList) {
super();
this.url = url;
this.protocol = protocol;
this.params = params;
this.postData = postData;
this.fileList = fileList;
createServiceUrl();
}
public String connectToMULTIPART_POST_service(String postName) {
System.out.println(">>>>>>>>>url : " + url);
StringBuilder stringBuilder = new StringBuilder();
String strResponse = "";
InputStream inputStream = null;
HttpURLConnection urlConnection = null;
try {
urlConnection = (HttpURLConnection) new URL(url.toString()).openConnection();
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setRequestProperty("Connection", "close");
urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 ( compatible ) ");
urlConnection.setRequestProperty("Authorization", "Bearer " + Config.getConfigInstance().getAccessToken());
urlConnection.setRequestProperty("Content-type", "multipart/form-data; boundary=" + boundary);
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setUseCaches(false);
urlConnection.setChunkedStreamingMode(1024);
urlConnection.setRequestMethod("POST");
dos = new DataOutputStream(urlConnection.getOutputStream());
Iterator<String> keys = postData.keys();
while (keys.hasNext()) {
try {
String id = String.valueOf(keys.next());
addFormField(id, "" + postData.get(id));
System.out.println(id + " : " + postData.get(id));
} catch (JSONException e) {
e.printStackTrace();
}
}
try {
dos.writeBytes(LINE_FEED);
dos.flush();
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
if (fileList != null && fileList.size() > 0 && !fileList.isEmpty()) {
for (int i = 0; i < fileList.size(); i++) {
File file = new File(fileList.get(i));
if (file != null) ;
addFilePart("photos[" + i + "][image]", file);
}
}
// forming th java.net.URL object
build();
urlConnection.connect();
int statusCode = 0;
try {
urlConnection.connect();
statusCode = urlConnection.getResponseCode();
} catch (EOFException e1) {
if (count < 5) {
urlConnection.disconnect();
count++;
String temp = connectToMULTIPART_POST_service(postName);
if (temp != null && !temp.equals("")) {
return temp;
}
}
} catch (IOException e) {
e.printStackTrace();
}
// 200 represents HTTP OK
if (statusCode == HttpURLConnection.HTTP_OK) {
inputStream = new BufferedInputStream(urlConnection.getInputStream());
strResponse = readStream(inputStream);
} else {
System.out.println(urlConnection.getResponseMessage());
inputStream = new BufferedInputStream(urlConnection.getInputStream());
strResponse = readStream(inputStream);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != inputStream)
inputStream.close();
} catch (IOException e) {
}
}
return strResponse;
}
public void addFormField(String fieldName, String value) {
try {
dos.writeBytes(TWO_HYPHENS + boundary + LINE_FEED);
dos.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\"" + LINE_FEED + LINE_FEED/*+ value + LINE_FEED*/);
/*dos.writeBytes("Content-Type: text/plain; charset=UTF-8" + LINE_FEED);*/
dos.writeBytes(value + LINE_FEED);
} catch (IOException e) {
e.printStackTrace();
}
}
public void addFilePart(String fieldName, File uploadFile) {
try {
dos.writeBytes(TWO_HYPHENS + boundary + LINE_FEED);
dos.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\";filename=\"" + uploadFile.getName() + "\"" + LINE_FEED);
dos.writeBytes(LINE_FEED);
FileInputStream fStream = new FileInputStream(uploadFile);
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int length = -1;
while ((length = fStream.read(buffer)) != -1) {
dos.write(buffer, 0, length);
}
dos.writeBytes(LINE_FEED);
dos.writeBytes(TWO_HYPHENS + boundary + TWO_HYPHENS + LINE_FEED);
/* close streams */
fStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void addHeaderField(String name, String value) {
try {
dos.writeBytes(name + ": " + value + LINE_FEED);
} catch (IOException e) {
e.printStackTrace();
}
}
public void build() {
try {
dos.writeBytes(LINE_FEED);
dos.flush();
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static String readStream(InputStream in) {
StringBuilder sb = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String nextLine = "";
while ((nextLine = reader.readLine()) != null) {
sb.append(nextLine);
}
/* Close Stream */
if (null != in) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
private void createServiceUrl() {
if (null == params) {
return;
}
final Iterator<Map.Entry<String, String>> it = params.entrySet().iterator();
boolean isParam = false;
while (it.hasNext()) {
final Map.Entry<String, String> mapEnt = (Map.Entry<String, String>) it.next();
url.append(mapEnt.getKey());
url.append("=");
try {
url.append(URLEncoder.encode(mapEnt.getValue(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
url.append(WSConstants.AMPERSAND);
isParam = true;
}
if (isParam) {
url.deleteCharAt(url.length() - 1);
}
}
}

Categories

Resources