Invalid image POST request JAVA - java

I try to upload an image file with POST request and get the following response from server:
Notice: Undefined index: width in /home/api.webbankir.com/methods/photo.php on line 32
Notice: Undefined index: width in /home/api.webbankir.com/methods/photo.php on line 37
Notice: Undefined index: height in /home/api.webbankir.com/methods/photo.php on line 32
Notice: Undefined index: height in /home/api.webbankir.com/methods/photo.php on line 37
Fatal error: Uncaught exception 'Exception' with message 'Invalid image:
/home/api.webbankir.com/tmp/d9864480da25e440ff4d591498881e79.jpg' in
/home/api.webbankir.com/include/Simpleimage.php:1081
Stack trace:#0 /home/api.webbankir.com/include/Simpleimage.php(512): SimpleImage->get_meta_data()
#1/home/api.webbankir.com/methods/photo.php(97): SimpleImage-
>load('/home/api.webba...')
#2 /home/api.webbankir.com/methods/photo.php(411): Photo->load(Array)
#3 {main}thrown in /home/api.webbankir.com/include/Simpleimage.php on line 1081
Here is my JAVA code:
HttpURLConnection connection = null;
DataOutputStream outputStream = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1024 * 1024;
try {
connection = null;
URL url = new URL(url_link);
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("ENCTYPE", "multipart/form-data");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
connection.setRequestProperty("file", "img_webbankir.jpeg");
outputStream = new DataOutputStream( connection.getOutputStream() );
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + "img_webbankir.jpeg" +"\"" + lineEnd); /* img_webbankir.jpeg */
outputStream.writeBytes(lineEnd);
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
int dimension = Math.min(bitmap.getWidth(), bitmap.getHeight());
bitmap = ThumbnailUtils.extractThumbnail(bitmap, dimension, dimension);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
b = baos.toByteArray();
imageEncoded = Base64.encodeToString(b, Base64.DEFAULT);
outputStream.writeBytes(imageEncoded);
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.e("log", "response code = " + serverResponseCode);
Log.e("log", "response message = " + serverResponseMessage);
outputStream.flush();
outputStream.close();
Log.e("log", "out put stream closed");
BufferedReader bufferedReader = new BufferedReader(new
InputStreamReader(connection.getInputStream()));
String line = "";
StringBuilder stringBuilder = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
bufferedReader.close();
response = stringBuilder.toString();
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
Log.e("Log", "error " + e);
}
I've tried the same request using OkHttp but got the same response...
I've also tried different ways of encoding the bitmap...
Will be grateful for help

Your client is in Java but error messages are from PHP. Therefore, it is server issue. Or you are not using server API properly. Are you integrating with 3-rd party, documented API or with your own PHP server?
If with your own server, you can debug the issue.
If we 3rd party API you should check their documentation if you are using API properly.
PS
for java rest client there are better, higher level tools than HttpURLConnection. Consider using https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html from spring.
https://github.com/square/okhttp or http://square.github.io/retrofit/ are also good choices. Your client code will be much shorter (2-5 lines, not 70), you will work on higher level of abstraction.
To reproduce the problem, please reproduce same post request with tools like Postman. https://www.getpostman.com/
That will rule out posibility of bug in your java code.

Related

Encoding multipart form data in Android

And Python there's a pretty standard code for sending a multipart-form data, or rather, encoding it:
def encode_multipart_formdata(fields, files):
# fields is a sequence of (name, value) elements for regular form fields.
# files is a sequence of (name, filename, value) elements for data to be uploaded as files
# Return (content_type, body) ready for httplib.HTTP instance
BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
L = []
for (key, value) in fields:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"' % key)
L.append('')
L.append(value)
for (key, filename, value) in files:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
L.append('Content-Type: %s' % get_content_type(filename))
L.append('')
L.append(value)
L.append('--' + BOUNDARY + '--')
L.append('')
body = CRLF.join(L)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
return content_type, body
I wonder, how can I do the same thing, encode multipart formdata, in Android?
I found a few solutions but none of them were supposed to do exactly the same thing as this one in python.
I checked if i used this code before, i can't really remember how exactly this works but here:
HttpURLConnection conn = null;
DataOutputStream dOut = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
URL url = new URL("http://shrimptalusan.hostei.com/usbong/build-upload.php");
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
setup the start of the multipart form:
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("utreeFile", utreeFilePath);
dOut = new DataOutputStream(conn.getOutputStream());
dOut.writeBytes(twoHyphens + boundary + lineEnd);
dOut.writeBytes("Content-Disposition: form-data; name=\"utreeFile\";filename=\"" + utreeFilePath + "\"" + lineEnd);
dOut.writeBytes(lineEnd);
bytesAvailable = utreeFileIn.available();
bufferSize = Math.min(bytesAvailable, maxBuffersize);
buffer = new byte[bufferSize];
bytesRead = utreeFileIn.read(buffer, 0, bufferSize);
Reading the file into a buffer:
while (bytesRead > 0) {
progress += bytesRead;
dOut.write(buffer, 0, bufferSize);
bytesAvailable = utreeFileIn.available();
publishProgress((int) ((progress * 100) / (utreeFile.length())));
bufferSize = Math.min(bytesAvailable, maxBuffersize);
buffer = new byte[bufferSize]; //TEST
bytesRead = utreeFileIn.read(buffer, 0, bufferSize);
}
Additional parameters to be included in the multipart entity:
//PARAMETER FIELD NAME
dOut.writeBytes(twoHyphens + boundary + lineEnd);
dOut.writeBytes("Content-Disposition: form-data; name=\"youtubelink\"" + lineEnd);
dOut.writeBytes(lineEnd);
dOut.writeBytes(youtubeLink); // mobile_no is String variable
dOut.writeBytes(lineEnd);
//PARAMETER END
Ending the multipart:
dOut.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
Sending the multipart via HTTP:
if (conn.getResponseCode() != HttpsURLConnection.HTTP_OK) {
utreeFileIn.close();
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
} else {
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
responseString += line;
}
}
Closing files and connections:
utreeFileIn.close();
dOut.flush();
dOut.close();
Hopefully it gives you a better idea. I don't think i used any external libraries. Here are my imports:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;

Can't upload file from android app to wep api

I am trying to upload an image file from an android app using java to an aspnet webapi with no success. I always get a response code of 500. Below is the basic code for preparing the sending of data from my android app. This code works when calling a php script but not when I call a web api controller shown below.
FileInputStream fileInputStream = new FileInputStream(sourceFile);
url = new URL("http://www.myserver.com/webapi/api/fileupload/post/thisfile");
connection = (HttpURLConnection) url.openConnection();
// Allow Inputs & Outputs.
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// Set HTTP method to POST.
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
outputStream = new DataOutputStream( connection.getOutputStream() );
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\"" + sourceFile +"\"" + lineEnd);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
serverResponseCode = connection.getResponseCode();
Below is the basic web api controller code to do the file upload:
[HttpPost]
[AcceptVerbs("GET", "POST")]
public Task<HttpResponseMessage> Post()
{
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
// return "Unsupported media type";
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = "e:/web/myserver/htdocs/cemetery/pics/";
var provider = new MultipartFormDataStreamProvider(root);
return task;
}
I changed the code above to send back a string and it says that my request does not contain multipart/form-data. Below is my webapiconfig.cs file route for this controller.
config.Routes.MapHttpRoute(
name: "FileUploadApi",
routeTemplate: "api/{controller}/{action}/{name}",
defaults: new { action = "post", name = RouteParameter.Optional }
);
I appreciate any help in determining what is wrong with my code so I can upload a file from an android java app to a webapi controller.

HttpURLConnection and writing file WITH DATA

I'm trying to post a file and data to my server from an Android java script (to my php), it seems I'm pretty much there, but someone PLEASE help me, as I can't seem to format the name/value part (the FILE uploads perfect, but it doesn't send the name value :( )
JAVA:
try{
int serverResponseCode = 0;
final String upLoadServerUri = "http://myUrl/upload_file_functions.php";
String fileName = "/mnt/sdcard/myFile.dat";
HttpURLConnection conn = null;
DataOutputStream dos = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
File sourceFile = new File("/mnt/sdcard/myFile.dat");
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL(upLoadServerUri);
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("file", fileName);
conn.setRequestProperty("gmail", names[0]);
conn.setRequestProperty("phn", phn);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\""
+ fileName + "\"" + lineEnd);
dos.writeBytes(twoHyphens + boundary + lineEnd);
String data = URLEncoder.encode("gmail", "UTF-8") + "=" + URLEncoder.encode(names[0], "UTF-8");
dos.writeBytes(data);
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);
dos.writeBytes("Content-Disposition: form-data; name=\"" + names[0] + "\"" + lineEnd);
dos.writeBytes("Content-Type: text/plain"+lineEnd);
dos.writeBytes(lineEnd);
dos.writeBytes(names[0]);
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
//*************************
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
String serverResponseMessage = conn.getResponseMessage();
Log.i("uploadFile", "HTTP Response is : "
+ serverResponseMessage + ": " + serverResponseCode);
if(serverResponseCode == 200){
// it worked !
}
//close the streams //
fileInputStream.close();
dos.flush();
dos.close();
}catch (Exception e){
}
It doesn't work, the FILE sends fine, but I can't get a freaking key/name to send ("gmail:"names[0]) I've also tried:
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("gmail", names[0]);
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\""
+ fileName + "\"" + lineEnd);
dos.writeBytes(twoHyphens + boundary + lineEnd);
DOESN'T WORK. I've tried:
dos.writeBytes("Content-Disposition: form-data; name=\"gmail\";filename=\""+ names[0] + "\"" + lineEnd);
Doesn't WORK! WTF! I've programmed for years in C++ and python, it's a simple thing! But I can't figure this out I need help, if you know how to do it PLEASE DO TELL because I've spent two days banging my head against the wall. I'm not lazy I spent 32+ f'n hours on this please I beg you..
What I WANT to happen: send the file for upload, along with the value (name=gmail value=names[0]; name=phn value=phn), so that the email is associated to the file on my server.
What IS happening: file is uploading fine, but data is not passed (the name/value pairs are not sent)
PHP:
<?php
set_time_limit(100);
//need to get email also (gmail address of user)
//************************************************
if ($_FILES["file"]["error"] > 0)
{
echo "Error: " . $_FILES["file"]["error"] . "<br>";
}
else
{
echo "Upload: " . $_FILES["file"]["name"] . "<br>";
echo "Type: " . $_FILES["file"]["type"] . "<br>";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "Stored in: " . $_FILES["file"]["tmp_name"];
move_uploaded_file($_FILES["file"]["tmp_name"],
"upload/" . $_FILES["file"]["name"]);
echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
}
}
function Three(){
$to = 'me#email.com';
$subject = $_POST['phn'] . " " . $_POST['gmail'];
$bound_text = "file";
$bound = "--".$bound_text."\r\n";
$bound_last = "--".$bound_text."--\r\n";
$headers = "From: me#email.com\r\n";
$headers .= "MIME-Version: 1.0\r\n"
."Content-Type: multipart/mixed; boundary=\"$bound_text\"";
$message .= "If you can see this MIME than your client doesn't accept MIME types!\r\n"
.$bound;
$message .= "Content-Type: text/html; charset=\"iso-8859-1\"\r\n"
."Content-Transfer-Encoding: 7bit\r\n\r\n"
."hey my <b>good</b> friend here is a picture of regal beagle\r\n"
.$bound;
$file = file_get_contents("http://myURL/upload/myFile.dat");
$message .= "Content-Type: image/jpg; name=\"myFile.dat\"\r\n"
."Content-Transfer-Encoding: base64\r\n"
."Content-disposition: attachment; file=\"myFile.dat"\r\n"
."\r\n"
.chunk_split(base64_encode($file))
.$bound_last;
#mail($to, $subject, $message, $headers);
//delete files
$fileArray=array($_FILES["file"]["name"],"myfile.dat","myfile.dat");
foreach($fileArray as $value){
if(file_exists($value)){
unlink($value);
}
}
chdir($old_path);
}
function runAll(){
One();
Two();
Three();
}
runAll();
$randx=null;
unset($randx);
?>
PLEASE HELP! The JAVA is not sending the name='gmail' value=names[0], nor the name='phn' value=phn ..
You should really read up on a few things: HTTP (and the distinction between request header fields and the post body), and the structure of a multipart/form-data post body.
This:
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("file", fileName);
conn.setRequestProperty("gmail", names[0]);
conn.setRequestProperty("phn", phn);
sends a few request headers, which is fine for Content-Type and such, but not necessarily for the data you're posting. Lose all but the Content-Type line.
This:
dos.writeBytes(twoHyphens + boundary + lineEnd);
is the right way to start a post field (or file), you should output this for every posted field.
This:
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
signals that all fields have been sent, you should send this as the very last line.
Either use something like Wireshark to see what your final request looks like (either side will do; the device doing the request or the server handling it), or log your request so you can inspect it, and see if it is perfect. It has to be nearly perfect for the webserver/php to process it correctly.
Well, I never figured out how to send a simple string parameter with the file upload, but my workaround was to simply append the filename of the upload file to INCLUDE the string I wanted to send:
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
try{
Account[] accounts=AccountManager.get(this).getAccountsByType("com.google");
String myEmailid=accounts[0].toString(); Log.d("My email id that i want", myEmailid);
String[] names = new String[accounts.length];
for (int i = 0; i < names.length; i++) {
names[i] = accounts[i].name;
}
// THE DEVICE EMAIL ADDRESS WAS ONE OF THE DATA STRINGS I NEEDED TO SEND
File from = new File("/mnt/sdcard/","UPLOADFILE.DAT");
File to = new File("/mnt/sdcard/",names[0]+".BLOCK1."+"DATASTRING2"+".BLOCK2");
from.renameTo(to);
// DATASTRING2 is the SECOND piece of DATA I wanted to send
// SO YOU SEE I'M SIMPLY APPENDING THE UPLOAD FILE WITH THE DATA I WANT
// TO SEND WITH THE FILE, AND WHEN MY SERVER RECEIVES IT, I USE SOME SIMPLE
// PHP TO PARSE OUT WHATS BEFORE .BLOCK1. AND THEN .BLOCK2
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
try{
int serverResponseCode = 0;
final String upLoadServerUri = "http://MYURL/upload_file_functions.php";
String fileName = "/mnt/sdcard/"+names[0]+".BLOCK1."+"DATASTRING2"+".BLOCK2";
HttpURLConnection conn = null;
DataOutputStream dos = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
File sourceFile = new File("/mnt/sdcard/"+names[0]+".BLOCK1."+"DATASTRING2"+".BLOCK2"");
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL(upLoadServerUri);
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\""+ fileName + "\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
String serverResponseMessage = conn.getResponseMessage();
Log.i("uploadFile", "HTTP Response is : "
+ serverResponseMessage + ": " + serverResponseCode);
//close the streams //
fileInputStream.close();
dos.flush();
dos.close();
}catch (Exception e){
}
}catch (Exception e){
}
}
Thanks for the help! (THICK WITH SARCASM..) Seriously, I have to code in python, C++, java, PHP, on linux, Android, iPhone, Windows, MAC and Ubuntu... my work has me building Triple-Boot OS box's, building apps in Android and iPhone to support my business needs, and thus I must know PHP html and the like, needed to configure my own server because I needed email-notification services, so I needed to run my own email server (Exim on Ubuntu Server), and I've had to learn all this in the past 6 months.
Forgive me if my code's not pretty, but I don't have the luxury of time, as I'm going INSANE trying to keep up in the land of AI, Object recognition, and trying to make the rent (though I've learned enough to do so..)
DC:)

Image writing over URLConnection

I am trying to write an image over an HttpURLConnection.
I know how to write text but I am having real problems trying
to write an image
I have succeeded in writing to the local HD using ImageIO:
But I am trying to write Image by ImageIO on url and failed
URL url = new URL(uploadURL);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Content-Type", "multipart/form-data;
boundary=" + boundary);
output = new DataOutputStream(connection.getOutputStream());
output.writeBytes("--" + boundary + "\r\n");
output.writeBytes("Content-Disposition: form-data; name=\"" + FIELD_NAME + "\";
filename=\"" + fileName + "\"\r\n");
output.writeBytes("Content-Type: " + dataMimeType + "\r\n");
output.writeBytes("Content-Transfer-Encoding: binary\r\n\r\n");
ImageIO.write(image, imageType, output);
the uploadURL is the url to an asp page on the server which will upload the image with the file name given in "content-Disposition: part.
now when I send this then asp page find the request and find the name of file. but does not find the file to be uploaded.
The problem is that when writing by ImageIO on URL what will the name of the file on which the ImageIO is writing,
So please help me how ImageIO will write an image on URLConnection and how can I know the name of the file which I have to use in the asp page to upload the file
Thanks for taking the time to read this post
Dilip Agarwal
First I believe that you should call io.flush() and then io.close() after writing image.
Second content type seems strange for me. It seems that you are trying to submit form while it is actually image. I do not know what does your asp expect but typically when I write code that should transfer file over HTTP I send appropriate content type, e.g. image/jpeg.
Here is for example code snippet I extracted from one small utility that I wrote and I am using during my current work:
URL url = new URL("http://localhost:8080/handler");
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestProperty("Content-Type", "image/jpeg");
con.setRequestMethod("POST");
InputStream in = new FileInputStream("c:/temp/poc/img/mytest2.jpg");
OutputStream out = con.getOutputStream();
copy(in, con.getOutputStream());
out.flush();
out.close();
BufferedReader r = new BufferedReader(new InputStreamReader(con.getInputStream()));
// obviously it is not required to print the response. But you have
// to call con.getInputStream(). The connection is really established only
// when getInputStream() is called.
System.out.println("Output:");
for (String line = r.readLine(); line != null; line = r.readLine()) {
System.out.println(line);
}
I used here method copy() that I took from Jakarta IO utils. Here is the code for reference:
protected static long copy(InputStream input, OutputStream output)
throws IOException {
byte[] buffer = new byte[12288]; // 12K
long count = 0L;
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
Obviously the server side must be ready to read the image content directly from POST body.
I hope this helps.
The OP seems lost into oblivion but for the benefit of Mister Kite :
// main method
URL url = new URL(uploadURL);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true); // triggers "POST"
// connection.setDoInput(true); // only if needed
connection.setUseCaches(false); // dunno
final String boundary = Long.toHexString(System.currentTimeMillis());
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary="
+ boundary);
output = new DataOutputStream(connection.getOutputStream());
try {
// image must be a File instance
flushMultiPartData(image, output, boundary);
} catch (IOException e) {
System.out.println("IOException in flushMultiPartData : " + e);
return;
}
// ...
private void flushMultiPartData(File file, OutputStream serverOutputStream,
String boundary) throws FileNotFoundException, IOException {
// SEE https://stackoverflow.com/a/2793153/281545
PrintWriter writer = null;
try {
// true = autoFlush, important!
writer = new PrintWriter(new OutputStreamWriter(serverOutputStream,
charsetForMultipartHeaders), true);
appendBinary(file, boundary, writer, serverOutputStream);
// End of multipart/form-data.
writer.append("--" + boundary + "--").append(CRLF);
} finally {
if (writer != null) writer.close();
}
}
private void appendBinary(File file, String boundary, PrintWriter writer,
OutputStream output) throws FileNotFoundException, IOException {
// Send binary file.
writer.append("--" + boundary).append(CRLF);
writer.append(
"Content-Disposition: form-data; name=\"binaryFile\"; filename=\""
+ file.getName() + "\"").append(CRLF);
writer.append("Content-Type: "
+ URLConnection.guessContentTypeFromName(file.getName()))
.append(CRLF);
writer.append("Content-Transfer-Encoding: binary").append(CRLF);
writer.append(CRLF).flush();
InputStream input = null;
try {
input = new FileInputStream(file);
byte[] buffer = new byte[1024];
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
output.flush(); // Important! Output cannot be closed. Close of
// writer will close output as well.
} finally {
if (input != null) try {
input.close();
} catch (IOException logOrIgnore) {}
}
writer.append(CRLF).flush(); // CRLF is important! It indicates end of
// binary boundary.
}
You may want to add Gzip compression - see file corrupted when I post it to the servlet using GZIPOutputStream for a working class with or without Gzip. The ImageIO has no place here - just write the bytes past the wire and use ImageIO to your heart's content on the server. Based on #BalusC answer

Android file uploader with server-side php

I've been looking for a solution to this for hours, but I can't find any.
Basically, I want to upload, from my android device, files to an http website. However, I have no clue whatsoever how to do this. I'm using java on the device, and I would like to use PHP on the server-side of things. I just want to upload the files, not do anything fancy with them on the server.
Can anyone provide code and/or a good link to what I need? I have little to no experience in this, and I am at a loss.
Thanks,
NS
PS. I have no experience in PHP coding.
Yeah, so I found the java-side of things. This works, so... yeah.
public class Uploader extends Activity {
private String Tag = "UPLOADER";
private String urlString = "YOUR_ONLINE_PHP";
HttpURLConnection conn;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String exsistingFileName = "/sdcard/uploader/data/testfile";
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
try {
// ------------------ CLIENT REQUEST
Log.e(Tag, "Inside second Method");
FileInputStream fileInputStream = new FileInputStream(new File(
exsistingFileName));
// open a URL connection to the Servlet
URL url = new URL(urlString);
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
// Allow Inputs
conn.setDoInput(true);
// Allow Outputs
conn.setDoOutput(true);
// Don't use a cached copy.
conn.setUseCaches(false);
// Use a post method.
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos
.writeBytes("Content-Disposition: post-data; name=uploadedfile;filename="
+ exsistingFileName + "" + lineEnd);
dos.writeBytes(lineEnd);
Log.e(Tag, "Headers are written");
// create a buffer of maximum size
int bytesAvailable = fileInputStream.available();
int maxBufferSize = 1000;
// int bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[] buffer = new byte[bytesAvailable];
// read file and write it into form...
int bytesRead = fileInputStream.read(buffer, 0, bytesAvailable);
while (bytesRead > 0) {
dos.write(buffer, 0, bytesAvailable);
bytesAvailable = fileInputStream.available();
bytesAvailable = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bytesAvailable);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// close streams
Log.e(Tag, "File is written");
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
Log.e(Tag, "error: " + ex.getMessage(), ex);
}
catch (IOException ioe) {
Log.e(Tag, "error: " + ioe.getMessage(), ioe);
}
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(conn
.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
Log.e("Dialoge Box", "Message: " + line);
}
rd.close();
} catch (IOException ioex) {
Log.e("MediaPlayer", "error: " + ioex.getMessage(), ioex);
}
}
}
If you want to upload files that is larger than 2MB you need to edit your PHP configuraton
; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 2M
Eg:
; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 10M
That would allow you to upload files up to 10MB of size
For the PHP side of things take a look at
move_uploaded_file and also the global $_FILES
http://php.net/manual/en/function.move-uploaded-file.php
http://php.net/manual/en/features.file-upload.php

Categories