I am wondering here and there from last 2 days. My issue is that I am sending multiple files with some text/plain fields using multipart/form-data.
The issue is that when I am sending data using HTTPCLient its working fine but when I am trying to send data using HTTPURLConnection, server is not receiving anything, below is my MultipartUtility,
public class MultipartUtils extends NetworkUtility
{
private static final String END_REQUEST = "--";
private String mBoundary;
public MultipartUtils()
{
mBoundary = END_REQUEST + "quAxBSd";
}
public HttpURLConnection getUrlConnection(String URL, String httpMethod,
String contenttype, String boundry) throws Exception
{
URL url = new URL(URL);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
if (httpMethod.equalsIgnoreCase(HTTP_GET) == false)
urlConnection.setDoInput(true);
else
urlConnection.setDoInput(false);
urlConnection.setDoOutput(true);
urlConnection.setUseCaches(false);
urlConnection.setRequestMethod(httpMethod);
if (contenttype.equalsIgnoreCase(APPLICATION_MULTIPART))
{
urlConnection.setRequestProperty("Connection", "Keep-Alive");
urlConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundry);
urlConnection.setRequestProperty("ENCTYPE", "multipart/form-data");
}
else
{
urlConnection.setRequestProperty("Content-Type", contenttype);
}
return urlConnection;
}
public String uploadImagesAddPost(Activity mContext, String URL, String jsonString, ArrayList<ImageListBean> mImageBeanList) throws Exception
{
HttpURLConnection httpURLConnection = getUrlConnection(URL, HTTP_POST, APPLICATION_MULTIPART, mBoundary);
httpURLConnection.connect();
DataOutputStream dataOutputStream = new DataOutputStream(httpURLConnection.getOutputStream());
PrintWriter writer = new PrintWriter(new OutputStreamWriter(dataOutputStream, UTF8),
true);
addJsonToPart(writer, jsonString);
for (int i = 0; i < mImageBeanList.size(); i++)
{
try
{
byte[] imageByteArray = {};
Uri imageUri = mImageBeanList.get(i).getmUri();
String imagePath = ImageCaputureUtility.getPath(imageUri, mContext);
if (!imagePath.equals(""))
{
if (mImageBeanList.get(i).getmType().equalsIgnoreCase(MellTooConstants.IMG))
{
//For img
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 100, outputStream);
imageByteArray = outputStream.toByteArray();
addFileAsByte(dataOutputStream, "imageview" + (i + 1), imageByteArray, ("imageview" + (i + 1)) + ".jpeg", IMAGE_JPEG);
}
else
{
//For video
/* Uploading thumb*/
Bitmap bitmap = UtilsMellToo.createThumb(imageUri, mContext);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 100, outputStream);
imageByteArray = outputStream.toByteArray();
addFileAsByte(dataOutputStream, "imageview4", imageByteArray, "imageview4" + ".jpeg", IMAGE_JPEG);
/* Uploading video*/
imageByteArray = MellTooUtil.readFileToByteArray(new File(imagePath));
addFileAsByte(dataOutputStream, "video", imageByteArray, "video" + (i + 1) + ".mp4", VIDEO_MP4);
}
}
else
{
//No need to upload data
}
}
catch (Exception e)
{
e.printStackTrace();
}
if (i + 1 != mImageBeanList.size())
writer.append(mBoundary).append(CHANGE_LINE);
}
writer.append(mBoundary + END_REQUEST);
writer.flush();
return getResponse(httpURLConnection);
}
private void addJsonToPart(PrintWriter writer, String text)
{
writer.append(mBoundary).append(CHANGE_LINE);
writer.append(CONTENT_DISPOSITION + FORM_DATA + NAME + "\"formstring\"").append(CHANGE_LINE);
writer.append(CONTENT_TYPE + PLAIN_TEXT + CHARSET + UTF8).append(CHANGE_LINE);
writer.append(CONTENT_TRANSFER_ENCODING + "8bit").append(CHANGE_LINE);
writer.append(text).append(CHANGE_LINE);
writer.flush();
}
public void addFileAsByte(DataOutputStream outputStream, String fieldName, byte[] imageByteArray, String fileName, String contentType) throws IOException
{
PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream, UTF8),
true);
writer.append(mBoundary).append(CHANGE_LINE);
writer.append(CONTENT_DISPOSITION + FORM_DATA + NAME + "\"" + fieldName + "\";" + FILE_NAME + "\"" + fileName + "\"").append(CHANGE_LINE);
writer.append(CONTENT_TYPE + contentType).append(CHANGE_LINE);
writer.append(CONTENT_TRANSFER_ENCODING + BINARY).append(CHANGE_LINE);
writer.flush();
InputStream inputStream = new ByteArrayInputStream(imageByteArray);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.writeBytes(CHANGE_LINE);
outputStream.flush();
inputStream.close();
}
}
Below is the method, how I am using this class,
jsonResponseString = new MultipartUtils()
.uploadImagesAddPost(mContext, AppConstants.BASE_URL + AppConstants.SAVE_POST_URL,
mJsonString, mImageList);
Below is my ASP side,
HttpContextWrapper.Request.Form["formstring"]; //This is returning null
Please help me out from this...!!!
Thanks in advance
Below is my request,
After struggling approximately 4 days, I found the issue was in the boundry and the new line in the request....!
There should be a boundary and a blank line between text and image part and I was not using it. The blank line is separating the header from the boday of the each part of a multipart/form-data request...!
Related
I have tried relentlessly to create a succesfull file upload from my JAVA/Android project to Django/Python backend.
The file I am trying to upload is a wav audio file which is stored on the phone.
I am trying to mix two sets of code.
The Android code I am using is the one taken from: How to upload a WAV file using URLConnection.
public class curlAudioToWatson extends AsyncTask<String, Void, String> {
String asrJsonString="";
#Override
protected String doInBackground(String... params) {
String result = "";
try {
Log.d("Msg","**** UPLOADING .WAV to ASR...");
URL obj = new URL(ASR_URL);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
//conn.setRequestProperty("X-Arg", "AccessKey=3fvfg985-2830-07ce-e998-4e74df");
conn.setRequestProperty("Content-Type", "audio/wav");
conn.setRequestProperty("enctype", "multipart/form-data");
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
String wavpath=mRcordFilePath;
File wavfile = new File(wavpath);
boolean success = true;
if (wavfile.exists()) {
Log.d("Msg","**** audio.wav DETECTED: "+wavfile);
}
else{
Log.d("Msg","**** audio.wav MISSING: " +wavfile);
}
String charset="UTF-8";
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
String CRLF = "\r\n"; // Line separator required by multipart/form-data.
OutputStream output=null;
PrintWriter writer=null;
try {
output = conn.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(output, charset), true);
byte [] music=new byte[(int) wavfile.length()];//size & length of the file
InputStream is = new FileInputStream (wavfile);
BufferedInputStream bis = new BufferedInputStream (is, 16000);
DataInputStream dis = new DataInputStream (bis); // Create a DataInputStream to read the audio data from the saved file
int i = 0;
copyStream(dis,output);
}
catch(Exception e){
}
conn.connect();
int responseCode = conn.getResponseCode();
Log.d("Msg","POST Response Code : " + responseCode + " , MSG: " + conn.getResponseMessage());
if (responseCode == HttpURLConnection.HTTP_OK) { //success
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
Log.d("Msg","***ASR RESULT: " + response.toString());
JSONArray jresponse=new JSONObject(response.toString()).getJSONObject("Recognition").getJSONArray("NBest");
asrJsonString=jresponse.toString();
for(int i = 0 ; i < jresponse.length(); i++){
JSONObject jsoni=jresponse.getJSONObject(i);
if(jsoni.has("ResultText")){
String asrResult=jsoni.getString("ResultText");
//ActionManager.getInstance().addDebugMessage("ASR Result: "+asrResult);
Log.d("Msg","*** Result Text: "+asrResult);
result = asrResult;
}
}
Log.d("Msg","***ASR RESULT: " + jresponse.toString());
} else {
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
Log.d("Msg","POST FAILED: " + response.toString());
result = "";
}
} catch (Exception e) {
Log.d("Msg","HTTP Exception: " + e.getLocalizedMessage());
}
return result; //"Failed to fetch data!";
}
#Override
protected void onPostExecute(String result) {
if(!result.equals("")){
Log.d("Msg","onPostEXECUTE SUCCESS, consuming result");
//sendTextInputFromUser(result);
//ActionManager.getInstance().addDebugMessage("***ASR RESULT: "+asrJsonString);
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}else{
Log.d("Msg","onPostEXECUTE FAILED" );
}
}
}
public void copyStream( InputStream is, OutputStream os) {
final int buffer_size = 4096;
try {
byte[] bytes = new byte[buffer_size];
int k=-1;
double prog=0;
while ((k = is.read(bytes, 0, bytes.length)) > -1) {
if(k != -1) {
os.write(bytes, 0, k);
prog=prog+k;
double progress = ((long) prog)/1000;///size;
Log.d("Msg","UPLOADING: "+progress+" kB");
}
}
os.flush();
is.close();
os.close();
} catch (Exception ex) {
Log.d("Msg","File to Network Stream Copy error "+ex);
}
}
The Django backend code is taken from: https://simpleisbetterthancomplex.com/tutorial/2016/08/01/how-to-upload-files-with-django.html and I am using the simple upload:
def simple_upload(request):
if request.method == 'POST' and request.FILES['myfile']:
myfile = request.FILES['myfile']
fs = FileSystemStorage()
filename = fs.save(myfile.name, myfile)
uploaded_file_url = fs.url(filename)
return render(request, 'core/simple_upload.html', {
'uploaded_file_url': uploaded_file_url
})
return render(request, 'core/simple_upload.html')
I have already disabled the need for CSRF using #csrf_exempt.
I am getting the error "MultiValueDictKeyError" since Java does not post the file with the name 'myfile' for request.FILES['myfile'] to catch. Is have tried removing the ['myfile'] and just use request.FILES but then I get an error on
filename = fs.save(myfile.name, myfile)
saying there is no name to fetch.
Can I post the file so that it it catched by
request.FILES['myfile']
or is there better/simpler Django backend-code to use for communication with Android/IOS.
Thanks in advance and I apologize if this is a stupid question but I am dead stuck.
Here I go again answering my own question.
I found the following code from Android:How to upload .mp3 file to http server?
Using that instead of How to upload a WAV file using URLConnection and changing the line: dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + existingFileName + "\"" + lineEnd);
To dos.writeBytes("Content-Disposition: form-data; name=\"myfile\";filename=\"" + existingFileName + "\"" + lineEnd);
fixed my problem.
I want to upload Image to Perticular Url(www.myUrl.com/myFolderName/) through android and retrieve the address of that url.
Here is my code
class SaveFile extends AsyncTask<String,String,String>
{
FileInputStream fileInputStream;
HttpURLConnection connection;
URL url;
DataOutputStream outputStream;
int bytesRead,bytesAvailable,bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
File selectedFile = new File(selectedImagePath);
//selectedImagePath = path of Image in phonememory
#Override
protected String doInBackground(String... params)
{
Log.v(TAG,"Image path is " + selectedImagePath);
try
{
fileInputStream = new FileInputStream(selectedFile);
url = new URL(SEND_IMAGE);
connection= (HttpURLConnection)url.openConnection();
Log.v(TAG,"connection established");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection","Keep-Alive");
connection.setRequestProperty("ENCTYPE","multipart/form-data");
connection.setRequestProperty("Content-Type","multipart/form-data;boundary=*****");
//connection.setRequestProperty("image1",selectedImagePath);
//connection.setRequestProperty("user_id","1");
outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.writeBytes("--*****\r\n");
outputStream.writeBytes("Content-Disposition:form-data;name=\"uploaded_file\";filename=\""+selectedImagePath+"\""+"\r\n");
outputStream.writeBytes("\r\n");
//outputStream.writeBytes("--*****\r\n");
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("\r\n");
outputStream.writeBytes("--*****--\r\n");
int serverResponseCode = connection.getResponseCode();
String serverResponseMessage = connection.getResponseMessage();
if(serverResponseCode == HttpURLConnection.HTTP_OK) {
String line;
StringBuilder sb = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = reader.readLine()) != null) {
sb.append(line);
}
Log.v(TAG,"Response is " +sb.toString());
}
Log.v("UploadImage", "Server Response is: " + serverResponseMessage + ": " + serverResponseCode);
fileInputStream.close();
outputStream.flush();
outputStream.close();
}
catch (Exception e)
{
Log.v("UploadImage"," " + e.toString());
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
but I am getting serverResponse 404
I tried solutions like Uploading Image to Server - Android but not worked.
I searched a lot.but couldnt find solution
Please Help!!
I want to say that this maybe a server error. 404 in most cases is an error that says, "you have used wrong url". Check whether this url is correct.try to upload your data in your browser.
public class UploadProfilePicActivity extends Activity implements View.OnClickListener {
ImageView imageView;
Button btnUploadPic;
Button btnskipUploadPic;
Button btnSaveNContinue;
private static int RESULT_LOAD_IMAGE = 1;
String imagepath = null;
ProgressDialog dialog = null;
String url_profilePic;
private int serverResponseCode;
String api = "http://192.168.2.17:8000/api/v1/";
String format = "/?format=json";
AlmabayDatabase almabayDatabase;
String encodedString;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_uploadprofilepic);
imageView = (ImageView) findViewById(R.id.imageView);
btnUploadPic = (Button) findViewById(R.id.btnUploadPic);
btnskipUploadPic = (Button) findViewById(R.id.btnSkipUploadPic);
btnSaveNContinue = (Button) findViewById(R.id.btnSaveNContinue);
btnUploadPic.setOnClickListener(this);
btnSaveNContinue.setOnClickListener(this);
url_profilePic = api + "user-media" + format;
almabayDatabase = new AlmabayDatabase(this);
}
#Override
public void onClick(View v) {
if (v == btnUploadPic) {
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
} else if (v == btnSaveNContinue) {
dialog = ProgressDialog.show(UploadProfilePicActivity.this, "", "Uploading file...", true);
// messageText.setText("uploading started.....");
new Thread(new Runnable() {
public void run() {
Log.e("ImagePathTest", imagepath);
uploadFile(imagepath);
}
}).start();
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK) {
Uri selectedImageUri = data.getData();
imagepath = getPath(selectedImageUri);
Bitmap bitmap = BitmapFactory.decodeFile(imagepath);
imageView.setImageBitmap(bitmap);
Log.e("Uploading", "Uploading File :" + imagepath);
}
}
public String getPath(Uri uri) {
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
public int uploadFile(String imagepath) {
String fileName = imagepath;
Log.e("File Name", fileName);
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);
int pk = almabayDatabase.getUserID();
if (!sourceFile.isFile()) {
dialog.dismiss();
Log.e("uploadFile", "Source File not exist :" + imagepath);
runOnUiThread(new Runnable() {
public void run() {
Log.e("Sourcefile", "File doesn't exist");
}
});
return 0;
} else {
try {
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL(url_profilePic);
// 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("name", fileName);
// conn.setRequestProperty("timeline_id", String.valueOf(pk));
dos = new DataOutputStream(conn.getOutputStream());
//Send Image
Log.e("Sending","Sending Image");
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"name\";filename=\"" + fileName + "\"" + lineEnd);
dos.writeBytes(lineEnd);
// add parameter timeline_id
String timeline_id = String.valueOf(pk);
Log.e("Sending","Sending PK");
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"timeline_id\"" + lineEnd);
dos.writeBytes(lineEnd);
// assign value
dos.writeBytes(timeline_id);
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + 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();
Log.e("ResponseCode", String.valueOf(serverResponseCode));
String serverResponseMessage = conn.getResponseMessage();
Log.i("uploadFile", "HTTP Response is : "
+ serverResponseMessage + ": " + serverResponseCode);
if (serverResponseCode == 200) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(UploadProfilePicActivity.this, "File Upload Complete.", Toast.LENGTH_SHORT).show();
}
});
}
//close the streams //
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
dialog.dismiss();
ex.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
//messageText.setText("MalformedURLException Exception : check script url.");
Toast.makeText(UploadProfilePicActivity.this, "MalformedURLException", Toast.LENGTH_SHORT).show();
}
});
Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
} catch (Exception e) {
dialog.dismiss();
e.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
// messageText.setText("Got Exception : see logcat ");
Toast.makeText(UploadProfilePicActivity.this, "Got Exception : see logcat ", Toast.LENGTH_SHORT).show();
}
});
Log.e("Upload file failed", "Exception : " + e.getMessage(), e);
}
dialog.dismiss();
return serverResponseCode;
} // End else block
}
}
In this code ,I am trying to send image to server alongwith timeline_id .timeline_id contains the value pk that is the primary key of the user stored in the database.I am not able to send image with timeline_id.I don't know where the actual problem is.Please help me to resolve the issue.
You can simple put the file part along with the text part using the class below.
String charset = "UTF-8";
String requestURL = BASE_URL + "userregistration";
MultipartUtility multipart = new MultipartUtility(requestURL, charset);
multipart.addFormField("username", userJid);
multipart.addFilePart("image", imageBitmap);//ima
String response = multipart.finish();
Log.d("SERVER REPLIED", response);
You can create an MultipartUtility class as follow-
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;
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);
httpConn.setRequestProperty("api_key", "a05f9ece-cd34-11e4-afdc-1681e6b88ec1");
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("--").
append(boundary).
append(LINE_FEED).
append("Content-Disposition: form-data; name=\"").
append(name).append("\"").
append(LINE_FEED).
append("Content-Type: text/plain; charset=").
append(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 fileBytes a File to be uploaded
* #throws IOException
*/
public void addFilePart(String fieldName, byte[] fileBytes)
throws IOException {
// String fileName = uploadFile.getName();
writer.append("--")
.append(boundary)
.append(LINE_FEED)
.append("Content-Disposition: form-data; name=\"")
.append(fieldName)
.append("\"; filename=\"")
.append("user.jpeg")
.append("\"")
.append(LINE_FEED)
.append("Content-Type: image/jpeg")
.append(LINE_FEED)
.append("Content-Transfer-Encoding: binary")
.append(LINE_FEED)
.append(LINE_FEED);
writer.flush();
ByteArrayInputStream inputStream = new ByteArrayInputStream(fileBytes);
byte[] buffer = new byte[4096];
int bytesRead;
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).append(": ").append(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 String finish() throws IOException {
writer.append(LINE_FEED).flush();
writer.append("--")
.append(boundary)
.append("--")
.append(LINE_FEED)
.close();
String data = "";
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) {
data = data + line;
}
reader.close();
httpConn.disconnect();
} else {
throw new IOException("Server returned non-OK status: " + status);
}
return data.isEmpty() ? null : data;
}
}
I have fixed the issue.Just need to do the following changes in the uploadFile() method.Everything is working file now.
public int uploadFile(String imagepath) {
String fileName = imagepath;
Log.e("File Name", fileName);
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);
int pk = almabayDatabase.getUserID();
if (!sourceFile.isFile()) {
dialog.dismiss();
Log.e("uploadFile", "Source File not exist :" + imagepath);
runOnUiThread(new Runnable() {
public void run() {
// messageText.setText("Source File not exist :"+ imagepath);
Log.e("Sourcefile", "File doesn't exist");
}
});
return 0;
} else {
try {
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL(url_profilePic);
// 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("url", fileName);
// conn.setRequestProperty("timeline_id", String.valueOf(pk));
dos = new DataOutputStream(conn.getOutputStream());
// add parameter timeline_id
String timeline_id = String.valueOf(pk);
Log.e("Sending", "Sending PK");
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"timeline_id\"" + lineEnd);
dos.writeBytes(lineEnd);
// assign value
dos.writeBytes(timeline_id);
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + lineEnd);
//Send Image
Log.e("Sending", "Sending Image");
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"url\";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();
Log.e("ResponseCode", String.valueOf(serverResponseCode));
String serverResponseMessage = conn.getResponseMessage();
Log.i("uploadFile", "HTTP Response is : "
+ serverResponseMessage + ": " + serverResponseCode);
if (serverResponseCode == 200) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(UploadProfilePicActivity.this, "File Upload Complete.", Toast.LENGTH_SHORT).show();
}
});
}
//close the streams //
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
dialog.dismiss();
ex.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
//messageText.setText("MalformedURLException Exception : check script url.");
Toast.makeText(UploadProfilePicActivity.this, "MalformedURLException", Toast.LENGTH_SHORT).show();
}
});
Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
} catch (Exception e) {
dialog.dismiss();
e.printStackTrace();
runOnUiThread(new Runnable() {
public void run() {
// messageText.setText("Got Exception : see logcat ");
Toast.makeText(UploadProfilePicActivity.this, "Got Exception : see logcat ", Toast.LENGTH_SHORT).show();
}
});
Log.e("Upload file failed", "Exception : " + e.getMessage(), e);
}
dialog.dismiss();
return serverResponseCode;
} // End else block
}
Simply use the below method to send multiple files with json request...
mImagePath is the arraylist of image paths
// Method for sending files using multiparting......
public static String sendJsonWithFile(Activity mActivity, ArrayList<String> mImagePaths, String jsonString, String URL)
{
Log.e("json", jsonString);
String res = "";
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(URL);
String boundary = "*****" + Long.toString(System.currentTimeMillis()) + "*****";
boundary = "--" + boundary;
httppost.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
StringBody stringBody = new StringBody(jsonString);
reqEntity.addPart("formstring", stringBody);
for (int i = 0; i < mImagePaths.size(); i++)
{
String imagePath = mImagePaths.get(i);
if (mImagePaths != null && mImagePaths.size() > 0)
{
byte[] filebytes = FileUtils.readFileToByteArray(new File(imagePath));
ByteArrayBody filebodyImage = new ByteArrayBody(filebytes, "image");
Log.e("file path=", filebodyImage.toString());
reqEntity.addPart("image", filebodyImage);
}
}
httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
if (resEntity != null)
{
res = EntityUtils.toString(resEntity);
System.out.println(res);
}
if (resEntity != null)
{
resEntity.consumeContent();
}
httpclient.getConnectionManager().shutdown();
}
catch (UnsupportedEncodingException e)
{
res = "UnsupportedEncodingException";
e.printStackTrace();
}
catch (ClientProtocolException e)
{
res = "ClientProtocolException";
e.printStackTrace();
}
catch (FileNotFoundException e)
{
res = "FileNotFoundException";
e.printStackTrace();
}
catch (IOException e)
{
res = "IOException";
e.printStackTrace();
}
catch (Exception e)
{
res = "Exception";
e.printStackTrace();
}
return res;
}
I ran into a problem while trying to send some binary files(a 1.44 MB video and a png Image) along with some string params by using multipart-form. The problem is that after writing the headers and all the necessary stuff , when writing bytes on outputstream it blocks me from writing something else .
Can you please tell me what am i doing wrong !!
Here is my AsyncTask that sends data to the server
private class UploadUpAsyncTask extends AsyncTask<String, Void,
String>{
private String path;
private String lineend ="\r\n";
private String boundry = "****";
private String twoHiphens="--";
int bytesRead,bytesAvailable,bufferSize;
byte[] buffer;
int maxBufferSize = 1*1024*1024;
public UploadUpAsyncTask(String path){
this.path =path;
}
#Override
protected String doInBackground(String... urls) {
File file = new File(path);
File image = new File("/storage/emulated/0/DCIM/100MEDIA/error.png");
try {
URL url = new URL(urls[0]);
Log.d("UPLOAD", "URL ="+urls[0]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundry);
conn.setRequestProperty("Authorization", "----------------------------");
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.writeBytes(twoHiphens+boundry+lineend);
out.writeBytes("Content-Disposition: form-data; name=\"user_id\""+lineend+lineend);
out.writeBytes("1"+lineend);
out.writeBytes(twoHiphens+boundry+lineend);
out.writeBytes("Content-Disposition: form-data; name=\"preview_id\""+lineend+lineend);
out.writeBytes("1"+lineend);
out.writeBytes(twoHiphens+boundry+lineend);
out.writeBytes("Content-Disposition: form-data; name=\"categories_id\""+lineend+lineend);
out.writeBytes("2"+lineend);
out.writeBytes(twoHiphens+boundry+lineend);
out.writeBytes("Content-Disposition: form-data; name=\"title\""+lineend+lineend);
out.writeBytes("Mama"+lineend);
out.writeBytes(twoHiphens+boundry+lineend);
out.writeBytes("Content-Disposition: form-data; name=\"tags\""+lineend+lineend);
out.writeBytes("mama"+lineend);
out.flush();
out.writeBytes(twoHiphens+boundry+lineend);
out.writeBytes("Content-Disposition: form-data; name=\"video\"; filename=\""+file.getName()+"\""+lineend);
out.writeBytes(lineend);
Log.d("UPLOAD", "Titlul video-ului ="+file.getName());
//decoding of bytes from video
FileInputStream file_stream = new FileInputStream(file);
bytesAvailable =file_stream.available();
bufferSize = Math.min(bytesAvailable,maxBufferSize);
buffer = new byte[bufferSize];
Log.d("UPLOAD", "Bytes Read Video =" +bytesRead);
bytesRead = file_stream.read(buffer);
//writting to outputstream
while (bytesRead >0){
out.write(buffer, 0, bytesRead);
bytesRead=file_stream.read(buffer);
}
Log.d("UPLOAD", "Done Loading first buffer");
file_stream.close();
out.writeBytes(twoHiphens+boundry+lineend);
out.writeBytes("Content-Disposition: form-data; name=\"thumb\"; filename=\""+image.getName()+"\""+lineend);
out.writeBytes(lineend);
Log.d("UPLOAD", "Titlul preview-ului ="+image.getName());
//decodint image bytes
FileInputStream image_stream = new FileInputStream(image);
int bytesRead2;
int bytesAvailable2, bufferSize2 ;
bytesAvailable2 = image_stream.available();
bufferSize2 = Math.min(bytesAvailable2, maxBufferSize);
byte []buffer2 = new byte[bufferSize2];
//writing to outputstream
bytesRead2 = image_stream.read(buffer2);
while(bytesRead2>0){
out.write(buffer2, 0, bytesRead2); // bytesAvailable2 = image_stream.available();
bytesRead2 = image_stream.read(buffer2);
}
image_stream.close();
Log.d("UPLOAD", "Done loading the second buffer");
out.writeBytes(twoHiphens+boundry+twoHiphens+lineend);
out.writeBytes(lineend);
out.flush();
out.close();
Log.d("UPLOAD","Response Code = "+conn.getResponseCode());
String responseMessage = conn.getResponseMessage();
Log.d("UPLOAD", "Response Message = "+responseMessage);
InputStream in;
if(conn.getResponseCode() >= 400){
in = conn.getErrorStream();
}else{
in = conn.getInputStream();
}
BufferedReader reader = new BufferedReader(new InputStreamReader(in,"UTF-8"));
StringBuilder response = new StringBuilder();
char []bytes = new char[512];
int read ;
while((read = reader.read(bytes))!=-1){
response.append(bytes, 0, read);
}
Log.d("UPLOAD", "Response " +response);
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "maine";
}
#Override protected void onPostExecute(String result) {
super.onPostExecute(result); Log.d("UPLOAD", "Upload complete");
}
}
SOLVED !! The MIME Type selection of the files sent on the server was all wrong !
My upload code as below:
String end = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
try {
URL url = new URL(ActionUrl);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestMethod("POST");
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("Accept", "text/*");
con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
DataOutputStream ds = new DataOutputStream(con.getOutputStream());
ds.writeBytes(twoHyphens + boundary + end);
ds.writeBytes("Content-Disposition: form-data;" + "name=\"folder\"" + end + end);
ds.write(SavePath.getBytes("UTF-8"));
ds.writeBytes(end);
ds.writeBytes(twoHyphens + boundary + end);
ds.writeBytes("Content-Disposition: form-data;" + "name=\"Filedata\"; filename=\"");
ds.write(FileName.getBytes("UTF-8"));
ds.writeBytes("\"" + end);
ds.writeBytes(end);
FileInputStream fStream = new FileInputStream(uploadFilepath+""+FileName);
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int length = -1;
int pro = 0;
while((length = fStream.read(buffer)) != -1) {
ds.write(buffer, 0, length);
}
ds.writeBytes(end);
ds.writeBytes(twoHyphens + boundary + twoHyphens + end);
fStream.close();
ds.flush();
InputStream is = con.getInputStream();
int ch;
StringBuffer b = new StringBuffer();
while((ch = is.read()) != -1) {
b.append((char)ch);
}
ds.close();
}
catch(Exception e) {
e.printStackTrace();
}
While smaller than 16 mb, it upload success.
But while it more than 16 mb, the "OutOfMemory" error show.
How to avoid the outofmemory error?
Did you try using
con.setChunkedStreamingMode(1024);
This will help you to chunk your data into specific size, so that you need not keep your entire file in the memory.
UPDATE:
Try using the below method. I use this method to upload a 80 mb file without Exception.
public String sendFileToServer(String filename, String targetUrl) {
String response = "error";
Log.e("Image filename", filename);
Log.e("url", targetUrl);
HttpURLConnection connection = null;
DataOutputStream outputStream = null;
// DataInputStream inputStream = null;
String pathToOurFile = filename;
String urlServer = targetUrl;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
DateFormat df = new SimpleDateFormat("yyyy_MM_dd_HH:mm:ss");
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024;
try {
FileInputStream fileInputStream = new FileInputStream(new File(
pathToOurFile));
URL url = new URL(urlServer);
connection = (HttpURLConnection) url.openConnection();
// Allow Inputs & Outputs
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setChunkedStreamingMode(1024);
// 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);
String connstr = null;
connstr = "Content-Disposition: form-data; name=\"uploadedfile\";filename=\""
+ pathToOurFile + "\"" + lineEnd;
Log.i("Connstr", connstr);
outputStream.writeBytes(connstr);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
Log.e("Image length", bytesAvailable + "");
try {
while (bytesRead > 0) {
try {
outputStream.write(buffer, 0, bufferSize);
} catch (OutOfMemoryError e) {
e.printStackTrace();
response = "outofmemoryerror";
return response;
}
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
} catch (Exception e) {
e.printStackTrace();
response = "error";
return response;
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens
+ lineEnd);
// Responses from the server (code and message)
int serverResponseCode = connection.getResponseCode();
String serverResponseMessage = connection.getResponseMessage();
Log.i("Server Response Code ", "" + serverResponseCode);
Log.i("Server Response Message", serverResponseMessage);
if (serverResponseCode == 200) {
response = "true";
}
String CDate = null;
Date serverTime = new Date(connection.getDate());
try {
CDate = df.format(serverTime);
} catch (Exception e) {
e.printStackTrace();
Log.e("Date Exception", e.getMessage() + " Parse Exception");
}
Log.i("Server Response Time", CDate + "");
filename = CDate
+ filename.substring(filename.lastIndexOf("."),
filename.length());
Log.i("File Name in Server : ", filename);
fileInputStream.close();
outputStream.flush();
outputStream.close();
outputStream = null;
} catch (Exception ex) {
// Exception handling
response = "error";
Log.e("Send file Exception", ex.getMessage() + "");
ex.printStackTrace();
}
return response;
}
if Server accept chunked mode, you can use
((HttpURLConnection) con).setChunkedStreamingMode(chunkLength)
otherwise you can use
((HttpURLConnection) con).setChunkedStreamingMode(0);
or
/* compute first your request content length
contentLength = formBodyLength + yourFileSize
*/
con.setRequestProperty("Content-Length", String.valueOf(contentLength));
((HttpURLConnection) con).setFixedLengthStreamingMode(contentLength);
finally... send what you want
bitmap=Bitmap.createScaledBitmap(bitmap, 100, 100, true);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); //compress to format you want.
byte [] byte_arr = stream.toByteArray();
String image_str = Base64.encodeBytes(byte_arr);
Best Way I tried it was successful for me!!!