I have a JSP page that displays a PDF document when it is called. Assuming I generate the URL in this format:
http://localhost:8080/repository/file/view/viewPDF.jsp?fileID=27455
and send it to another user. The user can view the document (id:27455) on his browser with no problem. But let's say I want to hide the PDF toolbar shown so user is not allowed to access that toolbar.
I found that by entering this link:
http://localhost:8080/repository/file/view/viewPDF.jsp?fileID=27455#toolbar=0
Then this above will hide the toolbar but it's vulnerable since the other user can change it's value to 1 and the toolbar appears. I am thinking if it's possible to hide it internally in back end code instead but couldn't figure out how.
My viewPDF.jsp:
<%#page import="java.io.*"%>
<%#include file="../../../WEB-INF/jspf/mcre.jspf" %>
<%
response.setContentType("application/pdf");
boolean debug = true;
try {
String snodeid = request.getParameter("nodeID");
long nodeid = Long.parseLong(snodeid);
Pdfinfo pdf = PPFacade.getPDFInfo(nodeid);
String pdfpath = pdf.getFfullpath();
if (debug) {
System.out.println("=============== PDF STREAM ================");
System.out.println("pdfpath = "+ pdfpath);
}
//int len = (int)new File("D://test.pdf").length();
int len = (int)new File(pdfpath).length();
response.setContentLength(len);
byte[] buf = new byte[len];
FileInputStream pdfin = new FileInputStream(pdfpath);
pdfin.read(buf);
pdfin.close();
OutputStream pdfout = response.getOutputStream();
pdfout.write(buf,0,len);
pdfout.flush();
if (debug) {
System.out.println("=============== END PDF STREAM ================");
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
%>
<head>
PDF
</head>
Of course I know hiding #toolbar is not foolproof since any user with such knowledge can easily bypass it.
As the toolbar is a function of the browser, not the server or the pdf file, there's no way to force it to be shown or not without notifying the browser in some way.
And anyone intercepting the information that goes to the browser can indeed modify that information.
Of course even were you able to prevent that, they could always download the PDF to their file system and open it using any tool that allows reading PDFs, including such tools as they can create themselves.
So no, you can't lock down such things. And why would you even want to?
Closest you could come is embedding the PDF in a div that loads the PDF viewer browser plugin and uses an AJAX request to the server to retrieve the PDF content. But even then someone can intercept the request to the server and replicate that request using say curl and download the stream to a file directly.
Related
before someone tells me that there's already this question here, i must say i've tried basically every single example i've found.
The url i'm trying to download has a type of 'audio/wav', embedded in a video tag, or at least this is what i see when running Chrome's element inspector.
The matter is, the URL (which i can't post here) does not point to a .wav file nor anything, but to an ASP page, which seems to generate the audio.
So far so good, the problem here is that i can't really download the audio.
Basically my webclient is created like:
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_38); // Also tried Chrome here.
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setUseInsecureSSL(true);
webClient.getOptions().setPopupBlockerEnabled(false);
webClient.setAjaxController(new NicelyResynchronizingAjaxController());
HtmlPage page = (HtmlPage)webClient.getPage(URL);
I've tried creating an anchor element that links to the page containing the audio file:
HtmlElement createdElement = (HtmlElement) page.createElement("a");
createdElement.setAttribute("id", "link_som");
createdElement.setAttribute("href", "../sound.asp?app=audio");
page.appendChild(createdElement);
HtmlAnchor anc =(HtmlAnchor) page.getElementById("link_som", true); //tried this just to make sure it was returning the right anchor
InputStream inputStream = anc.click().getWebResponse().getContentAsStream();
//Writing the inputStream to a file generates a file which has 0 KB.
Also tried running the javascript that links to new URL through HtmlUnit:
ScriptResult resultado = page.executeJavaScript("window.open('../sound.asp?app=audio');");
webClient.waitForBackgroundJavaScript(5000);
HtmlPage paginaRes = (HtmlPage)resultado.getNewPage();
InputStream inputStream =paginaRes.getWebResponse().getContentAsStream(); //Here the inputStream also generates a 0 KB file
Interesting though, is that in all those cases i tried, if i write the inputStream to the console, it returns the main page source, for example:
int binary = 0;
while ((binary = inputStream.read()) != -1)
{
System.out.print((char)binary); //prints the old page source, and in some other tests, prints nothing.
}
Ps.: When opening the URL on chrome manually, it has an embedded player, on FireFox, it asks for Quicktime.
I am able using htmlunit to get audio element
FYI, my version is 2.15
I have solved this a long time already, then just to let others know.
The solution was giving up HTMLUnit and using Selenium with phamtomJS.
I have searched for a solution but so far nothing gives me the answer i want. My question is how to convert an existing jsp page to pdf using itext possibly after clicking a button. Can someone give me a proper exaple.
All i can find is methods like this.
public String createHtmlSnippet(Movie movie) {
StringBuffer buf = new StringBuffer("\t<span class=\"title\">");
buf.append(movie.getMovieTitle());
buf.append("</span><br />\n");
buf.append("\t<ul>\n");
for (Country country : movie.getCountries()) {
buf.append("\t\t<li class=\"country\">");
buf.append(country.getCountry());
buf.append("</li>\n");
}
buf.append("\t</ul>\n");
buf.append("\tYear: <i>");
buf.append(movie.getYear());
buf.append(" minutes</i><br />\n");
buf.append("\tDuration: <i>");
buf.append(movie.getDuration());
buf.append(" minutes</i><br />\n");
buf.append("\t<ul>\n");
for (Director director : movie.getDirectors()) {
buf.append("\t\t<li><span class=\"director\">");
buf.append(director.getName());
buf.append(", ");
buf.append(director.getGivenName());
buf.append("</span></li>\n");
}
buf.append("\t</ul>\n");
return buf.toString();
}
I want to give the url and generate and download the pdf.
You can call a servlet on the button click. And in the servlet the you can use PDF Renderer. It converts HTML to PDF directly. although it has certain Restrictions like all tags should be closed like doing this <input/> wont work .
You would have to do <input></input>. But the output is amazing and fast and since it HTML you can change it easily. It internally uses iText. If you use iText directly then it would be a tedious process.
And your question should be HTML to PDF not JSP to PDf cause the JSP will get execute to produce some HTML in the end anyways
You entire HTML should be in the StringBuffer or String format.
Download from here
Update Code:
// First create a temporry file
File file = File.createTempFile("temp","pdf");
String html= "<HMTL><BODY>Hello</BODY></HTML>"; // HTML content
/* in your case it would be File f = new File("URL OF PAGE");
* */
// Write the contents intot he file.
PrintWriter printWriter = new PrintWriter(file);
printWriter.print(html); // Write String in Temp file
printWriter.close();
String s ="YourFile.pdf"; // Name of Actual PDf file
PDFRenderer.renderToPDF(file,s);// Second parameter is the actual PDF file
// The PDF is now created in the default location of you web application
// Now just read it and send it in the response.
File finalPDf = new File(s); // Reference to the newly created PDF file
PrintWriter out = response.getWriter();
response.setContentType("application/pdf");
IOUtils.copy(new InputStreamReader(new FileInputStream(s)), out);
// The above method just reads from the PDF file and puts the data in the response object
// IOUtils fully qualified name: org.apache.commons.io.IOUtils
// PDF Renderer fully qualified name: org.xhtmlrenderer.simple.PDFRenderer
I had same requirement Docx4j worked for me.It has lot of helpers docx4j documentation
I want to show the file content in new tab in browser. What i have done is this:
int BUFF_SIZE = 102400;
FileInputStream is = null;
byte[] buffer = new byte[BUFF_SIZE];
int a = -1;
try
{
is = new FileInputStream(file);
ByteArrayOutputStream out = new ByteArrayOutputStream();
while((a = is.read(buffer)) != -1)
{
out.write(buffer);
}
out.flush();
out.close();
ServletOutputStream os = null;
os = response.getOutputStream();
os.write(out.toByteArray());
os.close();
is.close();
}
catch(Exception e)
{
// Exception handling
}
But this is leading to download of the file instead of opening the file-content in new tab.
I am not able to find what i am doing wrong.
Any help would be great!!
Actually, all you should need to do now is add JQuery to your webpage, and use JQUery.get. Once you get the html from the servlet, use jquery or javascript to set the text in your tab.
BTW, you might want to set other details on the servlet output stream, like file type, length etc. Just a thought
You could also try this with the omnifaces library
Faces.sendFile(file, false);//true makes it as an attachment
more information on http://omnifaces.org/docs/javadoc/1.8/org/omnifaces/util/Faces.html#sendFile(java.io.File,%20boolean)
A web application might not even know what is a brower. It receives requests through HTTP protocol and send responses through same protocol. The protocol by itsels knows nothing about browsers and tabs.
You must use javascript for anything that happens at browser level. Other answers adviced you to use jQuery. It is a well known javascript library that hides differences between browsers, but there are others around (dojo, extJs, ...) : Google and make your choice.
By the way, if all you want is open an URL in a new tab, that's one of the very few operations that you can do at HTML level. Just look at this example
from W3Schools.com :
Visit W3Schools!
that opens www.w3schools.com in a new tab (if browser has tabs what is now common) or a new window.
I'm doing a java web application that manage online auctions. At a certain point in the application the user can sell a product, so I have built a page where there is a form; in this form I have to handle the file upload using Oreilly Multipartrequest library. When I click the submit button a servlet should handle all the parameters, add the product on the database, and then redirect to the users page, but instead of doing it, the application hangs in a blank page. I'm using netbeans so I have checked the logs, but I can't find any errors; I have also checked on the logs inside the tomcat folder, but again I can't any errors. I don't know what to do neither where to search the solution.
Here is the part of the code that handle the upload:
try {
MultipartRequest multi =
new MultipartRequest(request, getServletContext().getRealPath("/img"), 10*1024*1024,
"ISO-8859-1", new DefaultFileRenamePolicy());
Enumeration files = multi.getFileNames();
while (files.hasMoreElements()) {
name = (String)files.nextElement();
filename = multi.getFilesystemName(name);
// String originalFilename = multi.getOriginalFileName(name);
// String type = multi.getContentType(name);
File f = multi.getFile(name);
if (f != null) {
session.setAttribute("success", "file written correctly");
}
}
} catch (IOException IEx) {
this.getServletContext().log("Error reading saving file");
}
Am I doing something wrong, or my idea is correct?
P.S. If the user decide not to upload any picture, I have to put on the database a default picture.
I am working on an application wherein I have to download a PPT file using a JSP page. I am using the following code, but it's not working.
<% try {
String filename = "file/abc.ppt";
// set the http content type to "APPLICATION/OCTET-STREAM
response.setContentType("APPLICATION/OCTET-STREAM");
// initialize the http content-disposition header to
// indicate a file attachment with the default filename
// "myFile.txt"
String disHeader = "Attachment Filename=\"abc.ppt\"";
response.setHeader("Content-Disposition", disHeader);
// transfer the file byte-by-byte to the response object
File fileToDownload = new File(filename);
FileInputStream fileInputStream = new
FileInputStream(fileToDownload);
int i;
while ((i=fileInputStream.read())!=-1)
{
out.write(i);
}
fileInputStream.close();
out.close();
}catch(Exception e) // file IO errors
{
e.printStackTrace();
}
%>
Can anybody solve this problem?
Not only the Content-Disposition header is incorrect, but you're incorrectly using JSP instead of a Servlet for this particular task.
JSP is a view technology. Everything outside the scriptlets <% %> will be printed to the response, including whitespace characters such as newlines. It would surely corrupt binary files.
You could trim the whitespace in the JSP file, but scriptlets are discouraged since a decade and nowadays considered bad practice. Raw Java code belongs in Java classes, not in JSP files. The real solution is to use a HttpServlet for this.
Create a class which extends HttpServlet, implement the doGet() method, move the Java code from the JSP file into this method, map this servlet on a certain url-pattern and your problem should disappear. You can find here a basic example of such a servlet.
Off the top there should be a semicolon in the Content-Disposition header ("attachment*;* filename ...)
You should also probably do a response.reset() before starting to set headers and stream. Internet Explorer has really strange rules about streaming files from secure sockets and won't work right if you don't clear the caching headers.