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());
Related
I am currently implementing the WOPI with my application. Our domain is already whitelisted by Microsoft. While implementation I am currently facing two problems as mentioned below:
The exception is thrown when trying to validate content as JSON: 'Unexpected character encountered while parsing value.' I am sending my response "Value=application/octet-stream" but I don't understand why the server is trying to parse the stream as JSON.
After every new request coming from "iframe" is initiating a new session in the JAVA.
Here are more details:
My current URL is https://onenote.officeapps-df.live.com/hosting/WopiTestFrame.aspx?ui=en-US&rs=en-US&dchat=1&hid=26D7CA2A10F60A68720106BF599F84B9&&WOPISrc=https://domain/wopiEditor/files/73346e47-697b-11e6-a8bc-c26cd8f74b91/courses/independentConcepts/concept_adminGlo_5/assets/Setting url for static ip.docx&access_token=DEADBEEFDEADBEEFDEADBEEF&access_token_ttl=1532765580679
And My Java code is as following:
public void getFile(HttpServletRequest request, HttpServletResponse response, String name) {
Println.getInstance().log(request.getSession().getId() + "re" + request.getRequestURI());
InputStream fis = null;
OutputStream toClient = null;
try {
String path = getFilePath(request) + name;
File file = new File(path);
String filename = file.getName();
// XWPFDocument xDoc = new XWPFDocument(OPCPackage.open(fis));
fis = new BufferedInputStream(new FileInputStream(path));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
response.reset();
response.addHeader("Content-Disposition",
"attachment;filename=" + new String(filename.getBytes("utf-8"), "ISO-8859-1"));
response.addHeader("Content-Length", "" + file.length());
response.addHeader("Content-Type", "" + "application/octet-stream");
//Println.getInstance().log(file.length() + "l" + file);
toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
toClient.write(buffer);
toClient.flush();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
fis.close();
toClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The test frame image is attached
The error you are seeing is on the CheckFileInfo request which is supposed to be returned as JSON. The Java snippit that you provided is for the getFile request which is a separate call that is made from the Office Online server. You should look over https://wopi.readthedocs.io/projects/wopirest/en/latest/ for how to write your implementation.
One thought is maybe you need to set the Content-Type header more specifically instead of the application/octet-stream you are sending?
Also there are quite a lot of other header values you are supposed to be returning, some of them may matter as well:
https://wopi.readthedocs.io/projects/wopirest/en/latest/common_headers.html#common-headers
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.
I am trying to download a part of file given the download URL using setRequestProperty("Range","bytes=" + startbytes + "-" + endbytes); The following code snippet shows what I am trying to do.
protected String doInBackground(String... aurl) {
int count;
Log.d(TAG,"Entered");
try {
URL url = new URL(aurl[0]);
HttpURLConnection connection =(HttpURLConnection) url.openConnection();
int lengthOfFile = connection.getContentLength();
Log.d(TAG,"Length of file: "+ lengthOfFile);
connection.setRequestProperty("Range", "bytes=" + 0 + "-" + 1000);
The problem is that, an exception is being raised, which says "Cannot set request property after connection is made". Please help me resolve this issue.
Option 1
If you do not need to know the content length:
[Beware, do not call the connection.getContentLength(). If you call that, you will get the exception. If you need to call it, then check the second option]
URL url = new URL(aurl[0]);
HttpURLConnection connection =(HttpURLConnection) url.openConnection();
connection.setRequestProperty("Range", "bytes=" + 0 + "-" + 1000);
//Note that, response code will be 206 (Partial Content) instead of usual 200 (OK)
if(connection.getResponseCode() == HttpURLConnection.HTTP_PARTIAL){
//Your code here to read response data
}
Option 2
If you need to know the content length:
URL url = new URL(aurl[0]);
//First make a HEAD call to get the content length
HttpURLConnection connection =(HttpURLConnection) url.openConnection();
connection.setRequestMethod("HEAD");
if(connection.getResponseCode() == HttpURLConnection.HTTP_OK){
int lengthOfFile = connection.getContentLength();
Log.d("ERF","Length of file: "+ lengthOfFile);
connection.disconnect();
//Now that we know the content lenght, make the GET call
connection =(HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Range", "bytes=" + 0 + "-" + 1000);
//Note that, response code will be 206 (Partial Content) instead of usual 200 (OK)
if(connection.getResponseCode() == HttpURLConnection.HTTP_PARTIAL){
//Your code here to read response data
}
}
Assuming you're using HTTP for the download, you'll want to use the HEAD http verb and RANGE http header.
HEAD will give you the filesize (if available), and then RANGE lets you download a byte range.
Once you have the filesize, divide it into roughly equal sized chunks and spawn download thread for each chunk. Once all are done, write the file chunks in the correct order.
If you don't know how to use the RANGE header, here's another SO answer that explains how: https://stackoverflow.com/a/6323043/1355166
[EDIT]
To make file into chunks use this, and start the downloading process,
private void getBytesFromFile(File file) throws IOException {
FileInputStream is = new FileInputStream(file); //videorecorder stores video to file
java.nio.channels.FileChannel fc = is.getChannel();
java.nio.ByteBuffer bb = java.nio.ByteBuffer.allocate(10000);
int chunkCount = 0;
byte[] bytes;
while(fc.read(bb) >= 0){
bb.flip();
//save the part of the file into a chunk
bytes = bb.array();
storeByteArrayToFile(bytes, mRecordingFile + "." + chunkCount);//mRecordingFile is the (String)path to file
chunkCount++;
bb.clear();
}
}
private void storeByteArrayToFile(byte[] bytesToSave, String path) throws IOException {
FileOutputStream fOut = new FileOutputStream(path);
try {
fOut.write(bytesToSave);
}
catch (Exception ex) {
Log.e("ERROR", ex.getMessage());
}
finally {
fOut.close();
}
}
I need to try connecting to url in the string request_url. If connection timeout occurs, I need to retry 2 more times before calling another url (ans.getUrl(2)) and repeat the same logic. Here is my code snippet. Can anyone help me out on the logic I need to be using here?
//ans.getUrl returns a url based on the int parameter you send. It can only be 1 and 2.
String request_url= ans.getUrl(1);
try {
URL url;
URLConnection urlConn;
DataInputStream input;
//URL Creation:
url = new URL(request_url);
// URL connection channel.
urlConn = url.openConnection();
urlConn.setConnectTimeout(2000);
urlConn.setDoInput(true);
urlConn.setDoOutput(true);
urlConn.setUseCaches(false);
// Get response data.
input = new DataInputStream(urlConn.getInputStream());
String str;
System.out.println("Response XML::: ");
while (null != ((str = input.readLine()))) {
System.out.println("XML:: "+str);
//Write to temp file for parsing
FileWriter fstream = new FileWriter("response.xml", true);
BufferedWriter out = new BufferedWriter(fstream);
out.write(str+"\n");
//Close the output stream
out.close();
}
//Close input
input.close();
} catch (FileNotFoundException e) {
System.err.println("FileNotFoundException: "
+ e.getMessage());
} catch (IOException e) {
System.err.println("Caught IOException: "
+ e.getMessage());
}
I would wrap the whole bit of code you posted in a function, and then apply the retry loop around that function. You'll need to allow the connect exception to propogate out to do this.
I try to access an ASPX-website where subsequent pages are returned based on
post data. Unfortunately all my attempts to get the following pages fail.
Hopefully, someone here has an idea where to find the error!
In step one I read the session ID from the cookie as well as the value of the
viewstate variable in the returned html page. Step two intends to send it
back to the server to get the desired page.
Sniffing the data in the webbrowser gives
Host=www.geocaching.com
User-Agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100618
Iceweasel/3.5.9 (like Firefox/3.5.9)
Accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language=en-us,en;q=0.5
Accept-Encoding=gzip,deflate
Accept-Charset=ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive=300
Connection=keep-alive
Referer=http://www.geocaching.com/seek/nearest.aspx?state_id=149
Cookie=Send2GPS=garmin; BMItemsPerPage=200; maprefreshlock=true; ASP.
NET_SessionId=c4jgygfvu1e4ft55dqjapj45
Content-Type=application/x-www-form-urlencoded
Content-Length=4099
POSTDATA=__EVENTTARGET=ctl00%24ContentBody%24pgrBottom%
24lbGoToPage_3&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPD[...]2Xg%3D%
3D&language=on&logcount=on&gpx=on
Currently, my script looks like this
import java.net.*;
import java.io.*;
import java.util.*;
import java.security.*;
import java.net.*;
public class test1 {
public static void main(String args[]) {
// String loginWebsite="http://geocaching.com/login/default.aspx";
final String loginWebsite = "http://www.geocaching.com/seek/nearest.aspx?state_id=159";
final String POST_CONTENT_TYPE = "application/x-www-form-urlencoded";
// step 1: get session ID from cookie
String sessionId = "";
String viewstate = "";
try {
URL url = new URL(loginWebsite);
String key = "";
URLConnection urlConnection = url.openConnection();
if (urlConnection != null) {
for (int i = 1; (key = urlConnection.getHeaderFieldKey(i)) != null; i++) {
// get ASP.NET_SessionId from cookie
// System.out.println(urlConnection.getHeaderField(key));
if (key.equalsIgnoreCase("set-cookie")) {
sessionId = urlConnection.getHeaderField(key);
sessionId = sessionId.substring(0, sessionId.indexOf(";"));
}
}
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
// get the viewstate parameter
String aLine;
while ((aLine = in.readLine()) != null) {
// System.out.println(aLine);
if (aLine.lastIndexOf("id=\"__VIEWSTATE\"") > 0) {
viewstate = aLine.substring(aLine.lastIndexOf("value=\"") + 7, aLine.lastIndexOf("\" "));
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(sessionId);
System.out.println("\n");
System.out.println(viewstate);
System.out.println("\n");
// String goToPage="3";
// step2: post data to site
StringBuilder htmlResult = new StringBuilder();
try {
String encoded = "__EVENTTARGET=ctl00$ContentBody$pgrBottom$lbGoToPage_3" + "&" + "__EVENTARGUMENT=" + "&"
+ "__VIEWSTATE=" + viewstate;
URL url = new URL(loginWebsite);
URLConnection urlConnection = url.openConnection();
urlConnection = url.openConnection();
// Specifying that we intend to use this connection for input
urlConnection.setDoInput(true);
// Specifying that we intend to use this connection for output
urlConnection.setDoOutput(true);
// Specifying the content type of our post
urlConnection.setRequestProperty("Content-Type", POST_CONTENT_TYPE);
// urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Cookie", sessionId);
urlConnection.setRequestProperty("Content-Type", "text/html");
DataOutputStream out = new DataOutputStream(urlConnection.getOutputStream());
out.writeBytes(encoded);
out.flush();
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String aLine;
while ((aLine = in.readLine()) != null) {
System.out.println(aLine);
}
} catch (MalformedURLException e) {
// Print out the exception that occurred
System.err.println("Invalid URL " + e.getMessage());
} catch (IOException e) {
// Print out the exception that occurred
System.err.println("Unable to execute " + e.getMessage());
}
}
}
Any idea what's wrong? Any help is very appreciated!
Update
Thank you for the fast reply!
I switched to use the HttpURLConnection instead of the URLConnection which implements the setRequestMethod(). I also corrected the minor mistakes you mentioned, e.g. removed the obsolete first setRequestProperty call.
Unfortunately this doesn’t change anything... I think I set all relevant parameters but still get the first page of the list, only. It seems that the "__EVENTTARGET=ctl00$ContentBody$pgrBottom$lbGoToPage_3" is ignored. I don't have any clues why.
Internally, the form on the website looks like this:
<form name="aspnetForm" method="post" action="nearest.aspx?state_id=159" id="aspnetForm">
It is called by the following javascript:
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['aspnetForm'];
if (!theForm) {
theForm = document.aspnetForm;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
Hopefully, this helps to find a solution?
Greetings
maik.
Do you actually want to GET or POST? If you want to POST, then you may need the setRequestMethd() line.
You're setting Content-Type twice -- I think you may need to combine these into one line.
Then, don't close the output stream before you try and read from the input stream.
Other than that, is there any more logging you can put in/clues you can give as to what way it's going wrong in?
Hey use following code
String userAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0";
org.jsoup.nodes.Document jsoupDoc = Jsoup.connect(url).timeout(15000).userAgent(userAgent).referrer("http://calendar.legis.ga.gov/Calendar/?chamber=House").ignoreContentType(true)
.data("__EVENTTARGET", eventtarget).data("__EVENTARGUMENT", eventarg).data("__VIEWSTATE", viewState).data("__VIEWSTATEGENERATOR", viewStateGenarator)
.data("__EVENTVALIDATION", viewStateValidation).parser(Parser.xmlParser()).post();