I'm developing a Java library for basic operations on SharePoint using Graph API.
I make a call on this entry point using SOAP UI:
https://graph.microsoft.com/v1.0/drives/{drive-id}/items/{item-id}/content
And I obtain a raw response:
%PDF-1.6
%âãÏÓ
1751 0 obj
<</Filter/FlateDecode/First 98/Length 322/N 11/Type/ObjStm>>stream
hޜԽJ1†á[ÉL’ó“–m,md±ÁElTü)¼{3“wXYDØ©¾3!ç<)&I^kˆ!ymÁ¤gë¥ÍE ...
endstream
endobj
startxref
2993893
%%EOF
It look like i'm retrieving an input stream.
In the HttpRequest class I try to build a response object that returns the InputStream. My property fileInputStream is an InputStream:
SharePointDownloadResponseModel returnValue = new SharePointDownloadResponseModel();
InputStream inputStream = new ByteArrayInputStream(response.toString().getBytes(StandardCharsets.UTF_8));
returnValue.setFileInputStream(inputStream);
return returnValue;
Now in my manager class I try to save the input stream in the hard drive. I handle 2 cases. First case, I have a fileName a folder to store the file. My request object :
if(request.getDownloadFolder() != null && request.getFileName() !=null) {
InputStream initialStream = returnValue.getFileInputStream();
FileOutputStream fos = new FileOutputStream(request.getDownloadFolder() + "/" + request.getFileName());
BufferedOutputStream bos = new BufferedOutputStream(fos );
// Read bytes from URL to the local file
byte[] buffer = new byte[4096];
int bytesRead = 0;
System.out.println("Downloading " + request.getFileName());
while ((bytesRead = initialStream.read(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.flush();
// Close destination stream
bos.close();
// Close URL stream
initialStream.close();
}
The document is created where it should be created but the file is damaged and can't be opened. I wonder what is the issue at this stage.
I finally solved my issue. Here is a basic method that shows my implementation :
public class DownloadFile {
public static void main(String[] args) throws IOException {
String url = "https://graph.microsoft.com/v1.0/drives/{driveId}/items/{itemId}/content";
SharePointCredentialRequest sharePointCredentialRequest = new SharePointCredentialRequest(Constants.TENANT_CLIENT_ID,
Constants.TENANT_CLIENT_SECRET, Constants.TENANT_AUTHORITY);
String token = Utils.getToken(sharePointCredentialRequest);
CloseableHttpClient client = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Authorization", "Bearer " + token);
try (CloseableHttpResponse response = client.execute(httpGet)) {
HttpEntity entity = response.getEntity();
if (entity != null) {
System.out.println(response.getAllHeaders().length);
System.out.println(entity.getContentEncoding());
System.out.println(entity.getContentLength());
System.out.println(entity.getContentType().getElements().toString());
try {
// do something useful with the stream
InputStream inputStream = IOUtils.toBufferedInputStream(response.getEntity().getContent());
File targetFile = new File("C:\\myFolder\\kant.pdf");
FileUtils.copyInputStreamToFile(inputStream, targetFile);
} catch (IOException | UnsupportedOperationException e) {
e.printStackTrace();
}
}
}
}
}
Related
Hi I was trying to read a PDF file online but after reading and writing on local. after viewing the document I am getting an error that content is not supported .
URL url1 =
new URL("http://www.gnostice.com/downloads/Gnostice_PathQuest.pdf");
byte[] ba1 = new byte[1024];
int baLength;
FileOutputStream fos1 = new FileOutputStream("/mnt/linuxabc/research_paper/Gnostice_PathQuest.pdf");
try {
URLConnection urlConn = url1.openConnection();
/* if (!urlConn.getContentType().equalsIgnoreCase("application/pdf")) {
System.out.println("FAILED.\n[Sorry. This is not a PDF.]");
} else {*/
try {
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");
}
// }
Your Pdf Link actually redirects to https://www.gnostice.com/downloads.asp, so there is no pdf directly behind the link.
Try with another link: check first in a browser of your choice that invoking the pdf's url render a real pdf in the browser.
The code below is practically the same as yours except for the pdf's url and the output's path, and I am also adding exception throws to the main method's signature and simply printing the content type.
It works as expected:
public class PdfFileReader {
public static void main(String[] args) throws IOException {
URL pdfUrl = new URL("http://www.crdp-strasbourg.fr/je_lis_libre/livres/Anonyme_LesMilleEtUneNuits1.pdf");
byte[] ba1 = new byte[1024];
int baLength;
try (FileOutputStream fos1 = new FileOutputStream("c:\\mybook.pdf")) {
URLConnection urlConn = pdfUrl.openConnection();
System.out.println("The content type is: " + urlConn.getContentType());
try {
InputStream is1 = pdfUrl.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");
}
}
}
}
Output:
The content type is: application/pdf
private static String readPdf() throws MalformedURLException, IOException {
URL url = new URL("https://colaboracion.dnp.gov.co/CDT/Sinergia/Documentos/Informe%20al%20Congreso%20Presidencia%202017_Baja_f.pdf");
BufferedReader read = new BufferedReader(
new InputStreamReader(url.openStream()));
String i;
StringBuilder stringBuilder = new StringBuilder();
while ((i = read.readLine()) != null) {
stringBuilder.append(i);
}
read.close();
return stringBuilder.toString();
}
I need to read a file (that is not available on web) on the server and output it to the user as a downloadable file.
The scenario is
The user click a link from an XPage
The request is sent to the server which reads a predefined file in the server file system
The file is brought back to the user as a downloadable file in the webbrowser.
The file on the server can be in any format, e.g .pdf, .exe, .doc etc
It does not matter if this is done on SSJS or in java.
I would really appreicate some code
Here is a similar question:
How to stream file from xPages?
And here is part of the Java code taken from there and completed by me (+a fix from you!). I have now tested it also and it works:
FacesContext facesContext = FacesContext.getCurrentInstance();
XspHttpServletResponse response = (XspHttpServletResponse) facesContext.getExternalContext().getResponse();
String strFileName = "myfile.txt";
String strFilePath= "c:" + File.separator + strFileName;
response.setContentType(URLConnection.guessContentTypeFromName(strFileName));
response.setHeader("Content-Disposition","attachment;filename=" + strFileName);
//File file = new File(strFilePath);
FileInputStream fileIn = new FileInputStream(strFilePath);
ServletOutputStream out = response.getOutputStream();
int iLen = 0;
byte[] btBuffer = new byte[10240]; // Not sure about optimal buffer size
while ((iLen = fileIn.read(btBuffer)) != -1) {
out.write(btBuffer, 0, iLen);
}
facesContext.responseComplete();
out.close();
You could do all this in SSJS also.
If guessContentTypeFromName does not guess it then you need to modify the definition file on server. Or if you have a limited set of file types you can place the MIME-type table in your code/application.
Here is the code I came up with to do this, def not production code.
public static byte[] grabFile(String readFile) throws IOException {
File file = new File(readFile);
ByteArrayOutputStream ous = new ByteArrayOutputStream();
InputStream ios = new FileInputStream(file);
try {
byte []buffer = new byte[4096];
int read = 0;
while ( (read = ios.read(buffer)) != -1 ) {
ous.write(buffer, 0, read);
}
} finally {
try {
if ( ous != null )
ous.close();
} catch ( IOException e) {
}
try {
if ( ios != null )
ios.close();
} catch ( IOException e) {
}
}
return ous.toByteArray();
}
public static void download() throws IOException {
byte[] data = grabFile("\\\\server\\path\\to\\file.pdf");
HttpServletResponse response = (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.reset();
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "attachment; filename=\"filename.pdf\"");
OutputStream output = response.getOutputStream();
output.write(data);
output.close();
FacesContext.getCurrentInstance().responseComplete();
}
Then just call the download method from the beforeRenderResponse of your Xpage
I open a txt file on my server, get the Int and want to increment the int by 1 and write it to the file again.
I get the file with this method:
public int getCount() {
try {
URL updateURL = new URL("http://myserver.gov/text.txt");
URLConnection conn = updateURL.openConnection();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while((current = bis.read()) != -1){
baf.append((byte)current);
}
/* Convert the Bytes read to a String. */
String tmp = new String(baf.toByteArray());
int count = Integer.valueOf(tmp);
return count;
} catch(Exception e) {
Log.e(TAG, "getAdCount Exception = " + e);
e.printStackTrace();
return -1;
}
}
now I simply increment the count and want to write it to the file.
I figured out, that it is possible to write to a file with this method:
BufferedWriter out = new BufferedWriter(new FileWriter("text.txt"));
out.write(count);
out.close();
But how I open the remote file? I dont find a way. Thanks!
##### Edit: #####
I have written this code:
URL url = new URL("http://myserver.gov/text.txt");
URLConnection con = url.openConnection();
con.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());
out.write(count);
out.close();
But it doesnt write the count to the file.
When you want to work with URLConnection you can follow the instructions here: Reading from and Writing to a URLConnection.
Update: You will also need a running server handling POST requests to update your counter.
According to me .When you are open remote file.Firstly you have to open connection than read file content.
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
than you can write file content.
How do I retrieve the contents of a file and assign it to a string?
The file is located on a https server and the content is plain text.
I suggest Apache HttpClient: easy, clean code and it handles the character encoding sent by the server -- something that java.net.URL/java.net.URLConnection force you to handle yourself:
String url = "http://example.com/file.txt";
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(new HttpGet(url));
String contents = EntityUtils.toString(response.getEntity());
Look at the URL Class in the Java API.
Pretty sure all you need is there.
First download the file from the server using the URL class of java.
String url = "http://url";
java.io.BufferedInputStream in = new java.io.BufferedInputStream(new
java.net.URL(url).openStream());
java.io.FileOutputStream fos = new java.io.FileOutputStream("file.txt");
java.io.BufferedOutputStream bout = new BufferedOutputStream(fos,1024);
byte data[] = new byte[1024];
while(in.read(data,0,1024)>=0)
{
bout.write(data);
}
bout.close();
in.close();
Then read the downloaded file using FileInputStream class of java
File file = new File("file.txt");
int ch;
StringBuffer strContent = new StringBuffer("");
FileInputStream fin = null;
try {
fin = new FileInputStream(file);
while ((ch = fin.read()) != -1)
strContent.append((char) ch);
fin.close();
} catch (Exception e) {
System.out.println(e);
}
System.out.println(strContent.toString());
Best answer I found:
public static String readPage(String url, String delimeter)
{
try
{
URL URL = new URL(url);
URLConnection connection = URL.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line, lines = "";
while ((line = reader.readLine()) != null)
{
if(lines != "")
{
lines += delimeter;
}
lines += line;
}
return lines;
}
catch (Exception e)
{
return null;
}
}
This is the method I have in my java application. It is reading the bytes correctly, I have logged to see if it was. The problem is that the php is not realizing the data is there. I have tested and the .php reads that $_POST is set, but is empty.
public void screenshot(BufferedImage screenshot) {
try {
ImageIO.write(screenshot, "png",
new File(Environment.getStorageDirectory().toString()
.concat(File.separator + SCRIPT_NAME + ".png")));
HttpURLConnection httpUrlConnection;
OutputStream outputStream;
BufferedInputStream fileInputStream;
BufferedReader serverReader;
int totalBytes;
String response = "";
String serverResponse = "";
String localFileName = Environment.getStorageDirectory().toString()
.concat(File.separator + SCRIPT_NAME + ".png");
// Establish a connection
httpUrlConnection = (HttpURLConnection) new URL(
"http://www.scripted.it/scriptoptions/utils/saveScreenshot.php?user="
+ SupraCrafter.statHandler.getUser())
.openConnection();
httpUrlConnection.setDoOutput(true);
httpUrlConnection.setDoInput(true);
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.setRequestProperty("Content-type",
"application/x-www-form-urlencoded");
outputStream = httpUrlConnection.getOutputStream();
// Buffered input stream
fileInputStream = new BufferedInputStream(new FileInputStream(
localFileName));
// Get the size of the image
totalBytes = fileInputStream.available();
// Loop through the files data
for (int i = 0; i < totalBytes; i++) {
// Write the data to the output stream
outputStream.write(fileInputStream.read());
}
// Close the output stream
outputStream.close();
// New reader to get server response
serverReader = new BufferedReader(new InputStreamReader(
httpUrlConnection.getInputStream()));
// Read the servers response
serverResponse = "";
while ((response = serverReader.readLine()) != null) {
serverResponse = serverResponse + response;
}
System.out.println(serverResponse);
// Close the buffered reader
serverReader.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
URL url = new URL(
"http://scripted.it/scriptoptions/utils/setScreenshotStatus.php?user="
+ SupraCrafter.statHandler.getUser() + "&pass="
+ SupraCrafter.statHandler.getPass() + "&script="
+ SCRIPT_NAME + "&status=1");
BufferedReader in = new BufferedReader(new InputStreamReader(
url.openStream()));
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
}
Here is the .php file:
<?
// Config
$uploadBase = "../screenshots/";
$uploadFilename = $_GET['user'] . ".png";
$uploadPath = $uploadBase . $uploadFilename;
// Upload directory
if(!is_dir($uploadBase))
mkdir($uploadBase);
// Grab the data
$incomingData = file_get_contents('php://input');
// Valid data?
if(!$incomingData)
die("No input data");
// Write to disk
$fh = fopen($uploadPath, 'w') or die("Error opening file");
fwrite($fh, $incomingData) or die("Error writing to file");
fclose($fh) or die("Error closing file");
echo "Success";
?>
It always echos 'no input data.'
You are not encoding the content with application/x-www-form-urlencoded. You should not simply copy the bytes into the HTTP payload, but instead encode it correctly.
application/x-www-form-urlencoded is not the only possible way of encoding it, multipart/form-data is another common choice. Both are supported by almost all webservers, and as a consequence by PHP.
A tutorial on how to encode using Java is here : http://www.devx.com/Java/Article/17679
Why don't you use Apache's HttpClient or similar library that already do that tedious work for you?
Apache HttpClient : http://hc.apache.org/httpcomponents-client-ga/