I want to upload a pdf file with few parameters to my server from my android app. I have spent almost 2 days in searching answer but always a new problem arises when I try a solution. At present there is no error in this code but still the file is not getting uploaded nor the database is getting changed. Please help to rectify my code.
My code at present is like this:
1) Upload Function:
public void upload_file(String file_dir, String user_id,String path){
try {
String hyphen="--";
String boundary="Bound";
String newline="\r\n";
URL url = new URL("http://117.**.**.**.**:****/upload.php");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "mutlipart/form-data;boundary="+boundary);
DataOutputStream oStream = new DataOutputStream(conn.getOutputStream());
//First Send Parameters so that database can be changed
oStream.writeBytes(hyphen+boundary+newline);
oStream.writeBytes("Content-Type: text/plain\n");
oStream.writeBytes("Content-Disposition: form-data;name=\"u_id\"" + "\r\n");
oStream.writeBytes(user_id+newline);
//oStream.flush();
oStream.writeBytes(hyphen+boundary+newline);
oStream.writeBytes("Content-Type: text/plain\n");
oStream.writeBytes("Content-Disposition: form-data;name=\"path\"" + "\r\n");
oStream.writeBytes(path+newline);
//oStream.flush();
oStream.writeBytes(hyphen+boundary+newline);
oStream.writeBytes("Content-Type: application/pdf\n");
oStream.writeBytes("Content-Disposition: post-data;name=\"file\";" +
"filename=\"s1.pdf\"" + "\r\n");
FileInputStream file = new FileInputStream(file_dir);
int filesize=file.available();
Log.d("size", "" + filesize);
int buffersize = 1024*1024;
byte buff[] = new byte[buffersize];
int byteRead = file.read(buff, 0, buffersize);
while (byteRead > 0) {
oStream.write(buff, 0, byteRead);
byteRead = file.read(buff, 0, buffersize);
}
oStream.writeBytes(newline);
InputStream iStream = conn.getInputStream();
char arry[] = new char[1000];
Reader in = new InputStreamReader(iStream, "UTF-8");
StringBuilder response = new StringBuilder();
while(true){
int rsz = in.read(arry, 0, 1000);
if (rsz < 0)
break;
response.append(arry,0, rsz);
}
Log.d("String",response.toString());
Log.d("Response","Res.."+conn.getResponseCode());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
2) My php file at my server: upload.php
<?php
require_once 'db_connect.php';
$obj = new DB_Connect();
$conn = $obj->connect();
if(!$conn){
echo mysql_error();
}
var_dump($_POST);
var_dump($_REQUEST);
print_r($_FILES);
$file_path = "Docs/";
$u_id=$_POST["u_id"];
$path=$_POST["path"];
$file = $path."/".basename( $_FILES['file']['name']);
$qrry = mysql_query("insert into file values('$file','$u_id',now(),'pdf')");
if(!$qrry)
echo "error";
$file_path = $file_path . basename( $_FILES['file']['name']);
if(move_uploaded_file($_FILES['file']['tmp_name'], $file_path)) {
echo "success";
} else{
echo "fail";
}
?>
When I checked the echos from my php file I found that neither the parameter nor the file is received by it...So please help me to know what is mistake in this code.
Thanks in advance
You can use the minimal HTTPS Upload Library. Despite the name it works with HTTP as well. It is only about 20K and is really just a wrapper around HttpURLConnection so I find it very suitable for Android. It saves you from having to understand multipart upload, encoding and what not. It's available also from Maven Central.
Your example would look like this:
public static void main(String[] args) throws IOException {
HttpsFileUploaderConfig config =
new HttpsFileUploaderConfig(new URL("http://myhost/upload.php"));
Map<String,String> extraFields = new HashMap<>();
extraFields.put("u_id", "foo");
extraFields.put("path", "bar");
HttpsFileUploaderResult result = HttpsFileUploader.upload(
config,
Collections.singletonList(new UploadItemFile(uFile)), // your file
extraFields, // your fields
null);
if (result.isError()) {
throw new IOException("Error uploading to " + config.getURL() + ", " + result.getResponseTextNoHtml());
}
}
The multipart message produced by your program is wrong: Missing the main body, missing the boundary declaration... This is the format you should produce instead:
Message-ID: <000000001>
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_0_842618406.1437326651362"
------=_Part_0_842618406.1437326651362
Content-Type: application/octet-stream; name=myfile.pdf
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=myfile.pdf
<...binary data...>
------=_Part_0_842618406.1437326651362--
I truly recommend to you not to produce MIME messages from the scratch; instead you'll save yourself trouble by using the Java Mail API, for example with this program:
public void createMultipartMessage(File[] files, OutputStream out)
throws MessagingException,
IOException
{
Session session=Session.getDefaultInstance(System.getProperties());
MimeMessage mime=new MimeMessage(session);
Multipart multipart=new MimeMultipart();
BodyPart part;
// Send form data (as for http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2):
part=new MimeBodyPart();
part.setDisposition("Content-Disposition: form-data; name=\"<name>\"");
part.setContent("<value>");
multipart.addBodyPart(part);
// Send binary files:
for (File file : files)
{
part=new MimeBodyPart();
part.setFileName(file.getName());
DataHandler dh=new DataHandler(new FileDataSource(file));
part.setDataHandler(dh);
multipart.addBodyPart(part);
}
mime.setContent(multipart);
mime.writeTo(out);
}
You must include in your runtime the mail-1.4.1.jar and activation-1.1.1.jar libraries.
Related
I develop an Spring,Hibernate 5 project. I have to download Excel/pdf from another report app.
Locally in tomcat no any error or corruption. But when I deploy my project to Weblogic on Linux server, Pdf working properly but Excel data being corruption like in below image.Corupted Excel
The download takes place in jsp. And I tring to move it in servlet before.
Code part of download;
response.reset();
o = response.getOutputStream();
String typeStr = "application/vnd.ms-excel";
typeStr = typeStr + "; charset=UTF-8";
response.setContentType(typeStr);
response.setHeader("Content-disposition","attachment; filename=\"" + downloadName + "\"" + ".xls");
url1 = new URL(reportUrl);
HttpURLConnection http = (HttpURLConnection) url1.openConnection();
response.setHeader("User-Agent", "Mozilla/5.0");
response.setHeader("Accept-Language", "en-US,en;q=0.9");
response.setHeader("Content-Language", "en");
response.setHeader("Transfer-Encoding", "chunked");
response.setHeader("Accept-Encoding", "gzip, deflate");
http.setRequestMethod("GET");
http.setRequestProperty("Content-type", typeStr);
http.setRequestProperty("Accept-Encoding", "identity");
http.setDoOutput(true);
http.setDoInput(true);
http.connect();
i = http.getInputStream();
byte b[] = new byte[1024];
while (true) {
int length = i.read(b, 0, b.length);
if (length < 0)
break;
o.write(b, 0, length);
} // while()
http.disconnect();
o.flush();
o.close();
i.close();
} catch (Exception ex) {
ex.printStackTrace();
try {
i.close();
o.close();
} catch (Exception e) {
}
}
Thank you.
Problem is caused from html tags, I removed ALL html tags(html,body,head etc.) from jsp and problem was disappeared . . .
I have a http server that receive POST requests and fetches data from mysql database.
This is the relevant part of the server:
#Override
public void handle(HttpExchange he) throws IOException {
JSONArray jsonArr = null;
InputStreamReader isr = new InputStreamReader(he.getRequestBody(), "utf-8");
BufferedReader br = new BufferedReader(isr);
String query = br.readLine();
JSONObject postData=null;
try {
postData=Constants.parseQuery(query);
} catch (JSONException e) {
System.out.println("ERROR: SelectHandler,handle,parseQuery, on query: " + query);
}
// Object t=params.entrySet().
try {
query=Constants.getSelectQuery(postData);
jsonArr = MySQLQueryExecutor.getInstance().getItems(query);
} catch (JSONException e) {
System.out.println("ERROR: SelectHandler,handle,getItems, on query: " + query);
}
String encoding = "UTF-8";
String ret=jsonArr.toString();
he.getResponseHeaders().set("Content-Type", "application/json; charset=" + encoding);
he.sendResponseHeaders(200, ret.length());
System.out.println(ret);
OutputStream os = he.getResponseBody();
ret= URLDecoder.decode(ret, "UTF-8");
os.write(ret.toString().getBytes());
os.close();
}
I can see that the server handles the request and sends a response, but on the client side I get an error.
The error is due to utf8 characters in the response (hebrew chars that when I omit them the error is gone).
How can I fix this? Is this a server or client problem?
The length is wrong too. A bit further will go:
String encoding = "UTF-8";
String ret = jsonArr.toString();
he.getResponseHeaders().set("Content-Type", "application/json; charset=" + encoding);
//ret= URLDecoder.decode(ret, "UTF-8");
byte[] bytes = ret.getBytes(StandardCharsets.UTF_8);
he.sendResponseHeaders(200, bytes.length);
System.out.println(ret);
OutputStream os = he.getResponseBody();
os.write(bytes);
os.close();
a) You have a broken Content-Type header field. There is no charset parameter in application/json. See last sentence in https://greenbytes.de/tech/webdav/rfc7159.html#rfc.section.11
b) You need to send the bytes obtained from String.getBytes("UTF-8") and
c) That's also how to compute the content length (so after encoding as UTF-8 bytes, not before).
I've been surfing over this site looking for an example or "light at the end of the tunnel" about how to write a code that let me download a file from a REST server in PHP to a client in JAVA.
The client will make a GET request with an ID of the file, and then the PHP REST code should response with the file, and JAVA receive that file and store it in the Hard Drive.
Any idea...?
I tried to do the PHP Rest server like this...:
$file = 'path_to_file/file.mp3';
$content = readfile($file);
And this $content var, is sent as the response...
The client... I wrote is:
try {
URL url = new URL("url/to/rest/server");
HttpURLConnection conn (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "Content-Disposition: filename\"music.mp3\"");
if(conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code: " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
try {
String output;
File newFile = newFile("/some/path/file.mp3");
fileWriter fw = new FileWriter(newFile);
while ((output = br.readLine()) != null) {
fw.write(output);
}
fw.close();
} catch (IOException iox) {
//do
}
} catch (MalformedURLException e) {
//do
}
The problem with my examples is that when I receive the file on the client is kind of corrupted or something!... in my example with an mp3 file, any music player on the client says that file is corrupted or it doesn't work.
Thanks for any help.
When dealing with binary data (MP3 files) you should use InputStream and OutputStream and not Readers/Writers. Additionally, the BufferedReader.readLine() strips any 'newlines' from the output too.
Because you are using Readers/Writers, the binary data is being converted to Strings, and I am sure there's a lot of corruption happening.
Try the following:
InputStream is = conn.getInputStream();
byte[] buffer = new byte[10240]; // 10K is a 'reasonable' amount
try {
File newFile = newFile("/some/path/file.mp3");
FileOutputStream fos = new FileOutputStream(newFile);
int len = 0;
while ((len = is.read(buffer)) >= 0) {
fos.write(buffer, 0, len);
}
fos.close();
} catch (IOException iox) {
//do
}
I'm trying to download a file from
http://aula.au.dk/main/document/document.php?action=download&id=%2F%D8velsesvejledning+2012.pdf
but it dosen't appear to be a pdf, when i try downloading it with this code
import java.io.*;
import java.net.*;
public class DownloadFile {
public static void download(String address, String localFileName) throws IOException {
URL url1 = new URL(address);
byte[] ba1 = new byte[1024];
int baLength;
FileOutputStream fos1 = new FileOutputStream(localFileName);
try {
// Contacting the URL
System.out.print("Connecting to " + url1.toString() + " ... ");
URLConnection urlConn = url1.openConnection();
// Checking whether the URL contains a PDF
if (!urlConn.getContentType().equalsIgnoreCase("application/pdf")) {
System.out.println("FAILED.\n[Sorry. This is not a PDF.]");
} else {
try {
// Read the PDF from the URL and save to a local file
InputStream is1 = url1.openStream();
while ((baLength = is1.read(ba1)) != -1) {
fos1.write(ba1, 0, baLength);
}
fos1.flush();
fos1.close();
is1.close();
} catch (ConnectException ce) {
System.out.println("FAILED.\n[" + ce.getMessage() + "]\n");
}
}
} catch (NullPointerException npe) {
System.out.println("FAILED.\n[" + npe.getMessage() + "]\n");
}
}
}
Can you help me out here?
http://aula.au.dk/main/document/document.php?action=download&id=%2F%D8velsesvejledning+2012.pdf is not a pdf. The website gives an error this is why the script doesn't work:
SQL error in file /data/htdocs/dokeos184/www/main/inc/tool_navigation_menu.inc.php at line 70
As Marti said, the root cause of the problem is the fact that the script fails. I tested your program on a working pdf link, it works just fine.
This wouldn't have helped you in this case, but HttpURLConnection is a specialized subclass of URLConnection that makes communications with an http server a lot easier - eg direct access to error codes, etc.
HttpURLConnection urlConn = (HttpURLConnection) url1.openConnection();
// check the responsecode for e.g. errors (4xx or 5xx)
int responseCode = urlConn.getResponseCode();
2 step process with 2 libraries.
// 1. Use Jsoup to get the response.
Response response= Jsoup.connect(location)
.ignoreContentType(true)
// more method calls like user agent, referer, timeout
.execute();
// 2. Use Apache Commons to write the file
FileUtils.writeByteArrayToFile(new File(path), response.bodyAsBytes());
Thank you in advance.
I'd like to upload some bitmap image from my android app.
but , I can't get it.
Could you recommend some solutions for it.
or collect my source code?
ByteArrayOutputStream bao = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bao);
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(
"http://example.com/imagestore/post");
MultipartEntity entity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE );
byte [] ba = bao.toByteArray();
try {
entity.addPart("img", new StringBody(new String(bao.toByteArray())));
httppost.setEntity(entity);
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// Execute HTTP Post Request
HttpResponse response = null;
try {
response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
}
use httpmime for uploading Image
try this
http://vikaskanani.wordpress.com/2011/01/11/android-upload-image-or-file-using-http-post-multi-part/
I found this solution really well created and 100% working even with amazon ec2, take a look into this link:
Uploading files to HTTP server using POST on Android (link deleted).
Compare to previous answer, this solution doesn't require to import huge library httpmime from Apache.
Copied text from original article:
This tutorial shows a simple way of uploading data (images, MP3s, text files etc.) to HTTP/PHP server using Android SDK.
It includes all the code needed to make the uploading work on the Android side, as well as a simple server side code in PHP to handle the uploading of the file and saving it. Moreover, it also gives you information on how to handle the basic autorization when uploading the file.
When testing it on emulator remember to add your test file to Android’s file system via DDMS or command line.
What we are going to do is set the appropriate content type of the request and include the byte array as the body of the post. The byte array will contain the contents of a file we want to send to the server.
Below you will find a useful code snippet that performs the uploading operation. The code includes also server response handling.
HttpURLConnection connection = null;
DataOutputStream outputStream = null;
DataInputStream inputStream = null;
String pathToOurFile = "/data/file_to_send.mp3";
String urlServer = "http://192.168.1.1/handle_upload.php";
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1*1024*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);
// 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=\"uploadedfile\";filename=\"" + pathToOurFile +"\"" + 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();
serverResponseMessage = connection.getResponseMessage();
fileInputStream.close();
outputStream.flush();
outputStream.close();
}
catch (Exception ex)
{
//Exception handling
}
If you need to authenticate your user with a username and password while uploading the file, the code snippet below shows how to add it. All you have to do is set the Authorization headers when the connection is created.
String usernamePassword = yourUsername + “:” + yourPassword;
String encodedUsernamePassword = Base64.encodeToString(usernamePassword.getBytes(), Base64.DEFAULT);
connection.setRequestProperty (“Authorization”, “Basic ” + encodedUsernamePassword);
Let’s say that a PHP script is responsible for receiving data on the server side. Sample of such a PHP script could look like this:
<?php
$target_path = "./";
$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path))
{
echo "The file ". basename( $_FILES['uploadedfile']['name']).
" has been uploaded";
}
else
{
echo "There was an error uploading the file, please try again!";
}
?>;
Code was tested on Android 2.1 and 4.3. Remember to add permissions to your script on server side. Otherwise, the uploading won’t work.
chmod 777 uploadsfolder
Where uploadsfolder is the folder where the files are uploaded. If you plan to upload files bigger than default 2MB file size limit. You will have to modify the upload_max_filesize value in the php.ini file.