Update 3: I tried to execute this request against requestb.in insteaad of the Blobstore URL and the same exception occured, so this looks like a problem with my upload method using HttpURLConnection and not a Blobstore specific issue.
Update 2: Added code for creating the upload URL method at the bottom
Update 1: Added code and exact exception below the question. Hope the situation is clearer now.
Files are getting uploaded to the Blobstore using a POST request to the URL provided by the createUploadURL() method. However, App Engine still responds with a FileNotFoundException to the upload requests complaining that a file was not found at https://<app-id>.appspot.com/_ah/upload/<long-random-string>
What could be going on here?
Upload Code:
try {
MultipartUtility multipartUtility = new MultipartUtility(blobUploadURL, "UTF-8",writeListener);
multipartUtility.addFormField("key_name", keyName);
multipartUtility.addFilePart("file", fileName, is);
multipartUtility.finish();
} catch (IOException e) {
}
MultipartUtility Class:
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;
private WriteListener listener;
public static interface WriteListener{
void transferred(long num);
}
public MultipartUtility(String requestURL, String charset,WriteListener listener)
throws IOException {
this.charset = charset;
// creates a unique boundary based on time stamp
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.setChunkedStreamingMode(-1);
outputStream=httpConn.getOutputStream();
this.listener=listener;
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
true);
}
public void addFormField(String name, String value) {
writer.append("--" + boundary).append(LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
.append(LINE_FEED);
writer.append("Content-Type: text/plain; charset=" + charset).append(
LINE_FEED);
writer.append(LINE_FEED);
writer.append(value).append(LINE_FEED);
writer.flush();
}
public void addFilePart(String fieldName, String fileName, InputStream is)
throws IOException {
//String fileName = uploadFile.getName();
writer.append("--" + boundary).append(LINE_FEED);
writer.append(
"Content-Disposition: form-data; name=\"" + fieldName
+ "\"; filename=\"" + fileName + "\"")
.append(LINE_FEED);
writer.append(
"Content-Type: "
+ URLConnection.guessContentTypeFromName(fileName))
.append(LINE_FEED);
writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = is.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
writer.append(LINE_FEED);
writer.flush();
}
public void addHeaderField(String name, String value) {
writer.append(name + ": " + value).append(LINE_FEED);
writer.flush();
}
public List<String> finish() throws IOException {
List<String> response = new ArrayList<String>();
writer.append(LINE_FEED).flush();
writer.append("--" + boundary + "--").append(LINE_FEED);
writer.close();
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpConn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
response.add(line);
}
// checks server's status code first
int status = httpConn.getResponseCode();
if (status != HttpURLConnection.HTTP_OK) {
throw new IOException("Server returned non-OK status: " + status);
}
reader.close();
httpConn.disconnect();
return response;
}
}
IO Exception caught when the upload request is executed:
java.io.FileNotFoundException: https://<app-id>.appspot.com/_ah/upload/<random-long-string>
Code for creating the Blobstore upload URL: (Note that I can see the uploaded files in Blobstore and even confirm that the blob handler servlet is also getting the key of the uploaded blob despite this exception.)
BlobstoreService bs = BlobstoreServiceFactory.getBlobstoreService();
String blobUploadURL = bs.createUploadUrl("/save/blob");
Related
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();
}
When I call the web service it responds with 403 and some data in response like these.
{
"code": "[jwt_auth] invalid_email",
"message": "Dummy MEssage",
"data": {
"status": 403
}
}
My code is as given below
final AsyncTask<Void, String, String> waitForCompletion = new AsyncTask<Void, String, String>() {
ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
//Show Progress
}
#Override
public synchronized String doInBackground(Void... params) {
String res = "";
String charset = "UTF-8";
String requestURL = "www.myurl.com";
try {
MultipartUtility multipart = new MultipartUtility(requestURL, charset);
multipart.addFormField("username", email);
multipart.addFormField("password", password);
List<String> response = multipart.finish();
for (String line : response) {
System.out.println(line);
res = line;
Log.d("Message" , "Obtained" + response);
}
} catch (IOException ex) {
System.err.println(ex);
dismissProgressDialog(progressDialog);
}
return res;
}
#Override
protected void onPostExecute(String result) {
dismissProgressDialog(progressDialog);
if (hasValue(result)) {
UserLogin response = (new Gson()).fromJson(result, new TypeToken<UserLogin>() {
}.getType());
if (result.contains("message")) {
// Show error message
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
showMessageAlert(Html.fromHtml(response.getMessage(), Html.FROM_HTML_MODE_COMPACT), getString(R.string.app_name), LoginActivity.this);
} else {
showMessageAlert(Html.fromHtml(response.getMessage()), getString(R.string.app_name), LoginActivity.this);
}
} else {
setUserId(LoginActivity.this , String.valueOf(response.getUserId()));
setToken(LoginActivity.this, response.getToken());
setLoginInformation(LoginActivity.this, result);
Intent intent = new Intent(LoginActivity.this, PickSportsActivity.class);
startActivity(intent);
finish();
}
}
}
};
The Issue is how can I get the response when I am getting errors of 403 and 404 in response. How can I fetch the response that I am getting even when I get these errors.
Here is my Multipart Code
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;
StringBuilder result;
/**
* 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;
// creates a unique boundary based on time stamp
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.addRequestProperty("TOKEN", "Zml0c29vOmZpdHNvb0Aj");
// httpConn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
// httpConn.addRequestProperty("content-type", "application/x-www-form-urlencoded");httpConn.setRequestProperty("content-type", "application/x-www-form-urlencoded; charset=utf-8");
/* httpConn.setRequestProperty("User-Agent", "CodeJava Agent");
httpConn.setRequestProperty("Test", "Bonjour");*/
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("--" + boundary).append(LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
.append(LINE_FEED);
writer.append("Content-Type: text/plain; charset=" + charset).append(
LINE_FEED);
writer.append(LINE_FEED);
writer.append(value).append(LINE_FEED);
writer.flush();
result = new StringBuilder();
boolean first = true;
if (first)
first = false;
else
result.append("&");
try {
result.append(URLEncoder.encode(name, "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(value, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* Adds a upload file section to the request
* #param fieldName name attribute in <input type="file" name="..." />
* #param uploadFile a File to be uploaded
* #throws IOException
*/
public void addFilePart(String fieldName, File uploadFile)
throws IOException {
String fileName = uploadFile.getName();
writer.append("--" + boundary).append(LINE_FEED);
writer.append(
"Content-Disposition: form-data; name=\"" + fieldName
+ "\"; filename=\"" + fileName + "\"")
.append(LINE_FEED);
writer.append(
"Content-Type: "
+ URLConnection.guessContentTypeFromName(fileName))
.append(LINE_FEED);
writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();
FileInputStream inputStream = new FileInputStream(uploadFile);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();
writer.append(LINE_FEED);
writer.flush();
try {
result.append(URLEncoder.encode(fieldName, "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(fileName, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* 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 + ": " + 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 List<String> finish() throws IOException {
List<String> response = new ArrayList<String>();
writer.append(LINE_FEED).flush();
writer.append("--" + boundary + "--").append(LINE_FEED);
writer.close();
// checks server's status code first
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) {
response.add(line);
}
reader.close();
httpConn.disconnect();
}
else if(status==500){
throw new IOException("Server HTTP_INTERNAL_ERROR : " + status);
}else {
throw new IOException("Server returned non-OK status: " + status);
}
return response;
}
}
In your finish method code see the int variable status.
This status variable will provide you the response code returned from the server.
The if condition in the code checks for response code 200 & 500. You can add your own logic for the same.
Also you can simplify your finish method code by using StringBuilder instead of using arraylist as response.
I am getting 500 server error using multipart. Same server code is working while uploading image from iOS side. Following is my code for multipart image uploading.Server Side is using PHP.
public PostFile(String requestURL)
throws IOException {
// creates a unique boundary based on time stamp
URL url = new URL(requestURL);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setUseCaches(false);
httpConn.setDoOutput(true); // indicates POST method
httpConn.setDoInput(true);
httpConn.setRequestMethod("POST");
httpConn.setRequestProperty("Connection", "Keep-Alive");
httpConn.setRequestProperty("Cache-Control", "no-cache");
httpConn.setRequestProperty(
"Content-Type", "multipart/form-data;boundary=" + this.boundary);
request = new DataOutputStream(httpConn.getOutputStream());
}
private void saveFile() {
try {
PostFile postFile = new PostFile(URL);
//postFile.addFormField();
postFile.addFormField("userId", "25");
postFile.addFormField("accessToken", "h7lCesyM3XKjmjvjrdojzypUNPqA9MsB8PQIzZyWkYHtV43XcxPubUJ3EV8L");
// contact.accumulate("files",imgData);
postFile.addFormField("area", "dfs");
postFile.addFilePart("test.jpeg", getFileFromBitmap(uri));
postFile.finish();
} catch (IOException e) {
e.printStackTrace();
}
}
public void addFilePart(String fieldName, File uploadFile)
throws IOException {
String fileName = uploadFile.getName();
request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
request.writeBytes("Content-Disposition: form-data; name=\"" +
fieldName + "\";filename=\"" +
fileName + "\"" + this.crlf);
request.writeBytes("Content-Type: image/jpeg;" + this.crlf);
request.writeBytes(this.crlf);
// byte[] bytes = Files.readAllBytes(uploadFile.toPath());
request.write(getBytesFromFile(uploadFile));
}
using the below code, i am able to send a large file to the server, but i cant seem to find out how send a text with the file.(send the file plus extra data(username, password..) for example). and also receive it at the server side.
FileInputStream fileInputStream = new FileInputStream(new File(
pathToOurFile));
URL url = new URL(urlServer);
connection = (HttpURLConnection) url.openConnection();
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=\"uploadedVideos\";filename=\""
+ pathToOurFile + "\"" + lineEnd;
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);
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);
fileInputStream.close();
outputStream.flush();
outputStream.close();
the server part:
HttpPostedFile file = HttpContext.Current.Request.Files[0];
string fname = Path.GetFileName(file.FileName);
file.SaveAs(Server.MapPath(Path.Combine("~/UploadedVideos/" + Date + "/", fname)));
please any help will be appreciated.
i know i can do this using HttpClient, but its not working for me in case of large files so i want to use this way.
Use this,
private static String multipost(String urlString, MultipartEntity reqEntity) {
try {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.addRequestProperty("Content-length", reqEntity.getContentLength()+"");
conn.addRequestProperty(reqEntity.getContentType().getName(), reqEntity.getContentType().getValue());
OutputStream os = conn.getOutputStream();
reqEntity.writeTo(conn.getOutputStream());
os.close();
conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
return readStream(conn.getInputStream());
}
} catch (Exception e) {
Log.e("MainActivity", "multipart post error " + e + "(" + urlString + ")");
}
return null;
}
private static String readStream(InputStream in) {
BufferedReader reader = null;
StringBuilder builder = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
builder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return builder.toString();
}
and here you can set File, username and password as like below using MultipartEntiry.
private void uploadMultipartData() throws UnsupportedEncodingException {
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("fileToUpload", new FileBody(uploadFile));
reqEntity.addPart("uname", new StringBody("MyUserName"));
reqEntity.addPart("pwd", new StringBody("MyPassword"));
String response = multipost(server_url, reqEntity);
Log.d("MainActivity", "Response :"+response);
}
Note: You need to add httpmime jar in your libs folder.
this is my working code, i recalled copying this from somewhere, cant recall it...
package my.com.myapp.utils;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
/**
* This utility class provides an abstraction layer for sending multipart HTTP
* POST requests to a web server.
* #author www.codejava.net
*
*/
public class MultipartUtil {
private final String boundary;
private static final String LINE_FEED = "\r\n";
private HttpURLConnection httpConn;
protected String charset;
protected OutputStream outputStream;
protected PrintWriter writer;
public boolean cancel = false;
protected boolean last_item_is_file = false;
public static String LOG_TAG = "MultipartUtil";
/**
* This constructor initializes a new HTTP POST request with content type
* is set to multipart/form-data
* #param requestURL
* #param charset
* #throws IOException
*/
public MultipartUtil(String requestURL, String charset, Boolean send_auth)
throws IOException {
this.charset = charset;
// creates a unique boundary based on time stamp
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("User-Agent", "Android submit");
//addHeaderField("lang", AppConfig.getInstance().language);
//addHeaderField("country", AppConfig.getInstance().country);
//User user = AppConfig.getInstance().get_user();
/*
if (send_auth && user != null && user.authentication_token != null && !user.authentication_token.equalsIgnoreCase("")) {
Log.i(LOG_TAG, "user token: "+user.authentication_token);
addHeaderField("X-User-Email", user.email);
addHeaderField("X-User-Token", user.authentication_token);
} else {
Log.i(LOG_TAG, "not auth / not logged in");
}
*/
// httpConn.setRequestProperty("Test", "Bonjour");
}
public PrintWriter setup_writer() throws IOException {
outputStream = httpConn.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
true);
return writer;
}
/**
* Adds a form field to the request
* #param name field name
* #param value field value
*/
public void addFormField(String name, String value) {
writer.append("--" + boundary).append(LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
.append(LINE_FEED);
writer.append("Content-Type: text/plain; charset=" + charset).append(
LINE_FEED);
writer.append(LINE_FEED);
writer.append(value).append(LINE_FEED);
writer.flush();
last_item_is_file = false;
}
/**
* Adds a upload file section to the request
* #param fieldName name attribute in <input type="file" name="..." />
* #param uploadFile a File to be uploaded
* #throws IOException
*/
public void addFilePart(String fieldName, File uploadFile)
throws IOException {
String fileName = uploadFile.getName();
writer.append("--" + boundary).append(LINE_FEED);
writer.append(
"Content-Disposition: form-data; name=\"" + fieldName
+ "\"; filename=\"" + fileName + "\"")
.append(LINE_FEED);
writer.append(
"Content-Type: "
+ URLConnection.guessContentTypeFromName(fileName))
.append(LINE_FEED);
writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();
FileInputStream inputStream = new FileInputStream(uploadFile);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while (!cancel && (bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();
if (cancel) {
writer.close();
return;
}
writer.append(LINE_FEED);
writer.flush();
last_item_is_file = true;
}
public void addFileStreamPart(String fieldName, String fileName, InputStream inputStream)
throws IOException {
writer.append("--" + boundary).append(LINE_FEED);
writer.append(
"Content-Disposition: form-data; name=\"" + fieldName
+ "\"; filename=\"" + fileName + "\"")
.append(LINE_FEED);
writer.append(
"Content-Type: "
+ URLConnection.guessContentTypeFromName(fileName))
.append(LINE_FEED);
writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();
byte[] buffer = new byte[4096];
int bytesRead = -1;
while (!cancel && (bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();
if (cancel) {
writer.close();
return;
}
writer.append(LINE_FEED);
writer.flush();
last_item_is_file = true;
}
/**
* 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) {
httpConn.setRequestProperty(name, value);
//writer.append(name + ": " + value).append(LINE_FEED).flush();
//addFormField("headers["+name+"]", value);
//writer.append(name + ": " + value).append(LINE_FEED).flush();
}
public HttpURLConnection finish() throws IOException {
if (last_item_is_file)
writer.append(LINE_FEED).flush();
writer.append("--" + boundary + "--").append(LINE_FEED);
writer.close();
return httpConn;
}
}
I would like upload any data (Username, Description,..) and a photo from my Android-App to my Server (PHP-Script).
By searching for this i found a solution: How to take a photo and send to HTTP POST request with Android?
By click on my send button, the upload-process starts and the php-script works but the $_POST -Vars are empty? Can anybody help me? My request-code:
[...]
case R.id.btnSend:
String strName = tName.getText().toString();
String strEmail = tEmail.getText().toString();
String strDatum = tDatum.getText().toString();
String strBeschreibung = tBeschreibung.getText().toString();
nvPairs = new ArrayList<NameValuePair>(2);
nvPairs.add(new BasicNameValuePair("sender", "AndoidApp"));
nvPairs.add(new BasicNameValuePair("name", strName));
nvPairs.add(new BasicNameValuePair("email", strEmail));
nvPairs.add(new BasicNameValuePair("datum", strDatum));
nvPairs.add(new BasicNameValuePair("beschreibung", strBeschreibung));
nvPairs.add(new BasicNameValuePair("bild", bmpUrl));
new UploadTask().execute();
}
[...]
private class UploadTask extends AsyncTask<Void, Void, List<String>> {
#Override
protected List<String> doInBackground(Void... params) {
String response = "";
try {
response = new MultipartServer().postData(new URL(postUrl), nvPairs);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
On the MultipartServer-Code i changed the line:
if ((avatarName = pair.getName()).equals("avatar")) {
avatarPath = pair.getValue();
}
to this:
if ((avatarName = pair.getName()).equals("bild")) {
avatarPath = pair.getValue();
}
And the Variables "bmpUrl" and "postUrl" are set correctly at an another line in my code.
Thanks for your help! I found an solution for the problem. The problem was at the Script from How to take a photo and send to HTTP POST request with Android?
I changed it to this:
public class MultipartServer {
private static final String TAG = "MultipartServer";
private static final String crlf = "\r\n";
private static final String twoHyphens = "--";
private static final String boundary = "AaB03x"; //*****
private String avatarName = null;
private String avatarPath = null;
public String postData(URL url, List<NameValuePair> nameValuePairs) throws IOException {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(10000);
connection.setConnectTimeout(15000);
connection.setRequestMethod("POST");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Cache-Control", "no-cache");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
FileInputStream inputStream;
OutputStream outputStream = connection.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
for (NameValuePair pair : nameValuePairs) {
dataOutputStream.writeBytes(crlf);
dataOutputStream.writeBytes(twoHyphens + boundary + crlf);
dataOutputStream.writeBytes(
"Content-Disposition: form-data; name=\""
+ URLEncoder.encode(pair.getName(), "UTF-8")
+ "\";" + crlf);
dataOutputStream.writeBytes(crlf);
dataOutputStream.writeBytes(URLEncoder.encode(pair.getValue(), "UTF-8"));
if (pair.getName().equals("bild")) {
avatarName = pair.getName();
avatarPath = pair.getValue();
}
}
// Write Avatar (if any)
if (avatarName != null && avatarPath != null) {
dataOutputStream.writeBytes(crlf);
dataOutputStream.writeBytes(twoHyphens + boundary + crlf);
dataOutputStream
.writeBytes("Content-Disposition: form-data; name=\""
+ avatarName + "\";filename=\""
+ new File(avatarPath).getName() + "\";" + crlf);
dataOutputStream.writeBytes(crlf);
inputStream = new FileInputStream(avatarPath);
byte[] data = new byte[1024];
int read;
while ((read = inputStream.read(data)) != -1)
dataOutputStream.write(data, 0, read);
inputStream.close();
dataOutputStream.writeBytes(crlf);
dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + crlf);
}
dataOutputStream.flush();
dataOutputStream.close();
String responseMessage = connection.getResponseMessage();
Log.d(TAG, responseMessage);
InputStream in = connection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(in, "UTF-8"));
StringBuilder response = new StringBuilder();
char[] b = new char[512];
int read;
while ((read = bufferedReader.read(b)) != -1) {
response.append(b, 0, read);
}
connection.disconnect();
Log.d(TAG, response.toString());
return response.toString();
}
}