How to serve a file with JSP? - java

This may sound totally stupid, but is a case of real life :(
I'm able to display a HTML table with a "virtual" link name.
Something like this:
Xyz description document.doc
Xyz description documentB.doc
Xyz description documentC.doc
This doc id represents an id in the database ( for these docs are stored in a blob as byte[] )
Anyway. I'm able to get that id, query the database and retrieve the byte[] ( and even store it in a tmp file )
What I can't figure out how to do, is, that when the user click on the link ( and after I perform the db retrieval ) "serve" the byte[] to the user.
Now the very worst part, and what makes me ask this question here is, I need to do this with JSP only ( no servlet ) and without 3rd party libraries ( just... don't ask me why I hate it too )
So. How do I serve in a jsp the binary content of a byte array stored in the server file system
My first guest is:
<%
InputStream read // read the file form the fle system
response.getOutputStream().write( theBytesReader );
%>
Am I close to the solution?
Would this work to the client as if he had clicked really in the server for a real file?
Thanks in advance.

To the point, just write the same code in JSP as you would do in a Servlet class. You can practically copypaste it. Only ensure that you are not writinig any template text to the stream, this includes linebreaks and whitespace outside the scriptlets. Otherwise it would get written to the binary file as well and corrupt it.
If you have multiple scriptlet blocks, then you need to arrange them so that there's no linebreak between the ending %> of a scriptlet and the starting <% of the next scriptlet. Thus, e.g.
<%#page import="java.io.InputStream" %><%
//...
%>
instead of
<%#page import="java.io.InputStream" %>
<%
//...
%>

You need to set the MIME type in the HTTP response like below in addition to the sample code you provided.
response.setContentType("application/octet-stream");
Note, the application/octet-stream MIME type is used to indicate a binary file.

Please, please, please don't do this.
You're doing a disservice to your users.
HTTP is amazingly rich in terms of what it can do with files. Caching, chunking, random access, etc.
Take a look at something like FileServlet, and hammer that to fit. Yes, it's a Servlet, rather than a JSP, but this is what you want to do to be a good HTTP citizen.
Some containers have other options you can use, you can hack Tomcats DefaultServlet, etc.

Something like this...
InputStream instr = null;
try {
instr = new BufferedInputStream( new FileInputStream("file.txt") );
for(int x=instr.read(); x!=-1; x=instr.read()){
out.write(x);
}
} finally {
out.close();
if( instr != null) instr.close();
}
You will need this as the response to the click (either on a page reload or in another jsp file).
There are better buffering solutions you can do with the write using byte arrays rather than one at a time... I will leave that for you.
Sorry you are stuck in JSP scriptlet land...Hope this helps.

Related

Using JSP include to display generated HTML from servlet

My servlet calls a method, which generates a HTML file (different content each time), eg. "[Timestamp].html"
In my jsp I use
<% String time= (String)request.getAttribute("time");
String address= "resources/"+time+".html";
%>
<jsp:include page="<%=address %>"/>
to show the page.
But it gives an error that the requested resource is not available. If I go to [Timestamp].html, it's there.
So, I think my problem is because jsp:include gets the file during compilation, not translation, so the file hasn't been closed yet. Any suggestions for a better strategy for including new content?
Write the generated string directly to a JSP instead of generating a file. So you are saving IO costs and don't have to handle that error.

How to map server response retrieved in jsp to an iFrame

I'm using struts2 framework(java/js/html/css combo) for my webapp. I am reading a text file from server and I want to write the response to an iFrame present in the same jsp.
Flow:
(1) On click of a link, I pass the relative URL of the text file to jsp.
(2) When the jsp page loads, the java code in the jsp reads the file from server.
(3) Now this response has to be written to an iFrame present in the same jsp file
Can anyone plz help me in writing such response to an iFrame?
Thanks in advance :)
[code not tested, only a demostration of the concept]
here's some very rough idea as to how to fix your code, they definitly not the best but they should be enough to help you understand the concept.
However I'd still recommend going over the whole concept and maybe come up with a more efficent way to do what you need.
if you insist on using iframe, you need to make use of 2 seperate jsp as W3C says in "Implementing HTML Frames":
Any frame that attempts to assign as its SRC a URL used by any of its ancestors is treated as if it has no SRC URL at all (basically a blank frame).
so you'll need 2 jsp, the first one is basically what you have but the the src of the iframe changed to:
<iframe scrolling="yes" width="80%" height="200" src="second.jsp?content=<%=all%>" name="imgbox" id="imgbox">
and the second one will be something like :
<html><body><%= request.getAttribute("content") %></body></html>
From the code you've shown you forced a "content update" on the iframe by using javascript. The proper/usual way to update an iframe is to provide different input parameter to the second jsp and let it update it for you.
Finally, I'd recommend using JSTL as much as possible instead of scriptlets. It is much cleaner.
What you need to do is set the src attribute of the IFRAME to the jsp url when your link is clicked. Another way to do it is doing something like this:
<iframe src="" name="iframe_a"></iframe>
<p>W3Schools.com</p>
with the correct parameters of course

iText - generating files on the fly without needing a PDF file

I am trying to use iText for pdf file generation and I have a question regarding the generation. I would like to serve the PDF to the browser so that the browser displays it, without actually creating a file.
What would be the best approach to achieve this?
One limitation is that I would need to use it from a JSP page - something that would circumvent the "getOutputStream has already been called once" error is what I am looking for.
I would like to serve the PDF to the browser so that the browser displays it, without actually creating a file.
Just pass responsegetOutputStream() instead of new FileOutputStream to PdfWriter.
PdfWriter pdfWriter = PdfWriter.getInstance(document, response.getOutputStream());
// ...
One limitation is that I would need to use it from a JSP page - something that would circumvent the "getOutputStream has already been called once" error is what I am looking for.
Just remove any whitespace outside <% %> in JSP, including newlines. They are implicitly sent to the response by the response writer.
I.e. do NOT
<% page import="foo" %>
<% page import="bar" %>
<%
for (int i = 0; i < 1000; i++) {
out.println("I should not use scriptlets.");
}
%>
(newline here)
but more so
<% page import="foo" %><% page import="bar" %><%
for (int i = 0; i < 1000; i++) {
out.println("I should use servlets.");
}
%>
Or better, don't put Java code in JSP files. JSP files are designed to present template text like HTML, not to do entirely different things. Do that in a normal Java class like a servlet.
Write it to the servlet output stream, remembering to set the encoding to the correct value
This http://onjava.com/onjava/2003/06/18/dynamic_files.html explains how to do it

HtmlUnit - Convert an HtmlPage into HTML string?

I'm using HtmlUnit to generate the HTML for various pages, but right now, the best I can do to get the page into the raw HTML that the server returns is to convert the HtmlPage into an XML string.
This is somewhat annoying because the XML output is rendered by web browsers differently than the raw HTML would. Is there a way to convert an HtmlPage into raw HTML instead of XML?
Thanks!
page.asXml() will return the HTML. page.asText() returns it rendered down to just text.
I'm not 100% certain I understood the question correctly, but maybe this will address your issue:
page.getWebResponse().getContentAsString()
I think there is no direct way to get the final page as HTML.
asXml() returns the result as XML, asText() returns the extracted text content.
The best you can do is to use asXml() and "transform" it to HTML:
htmlPage.asXml().replaceFirst("<\\?xml version=\"1.0\" encoding=\"(.+)\"\\?>", "<!DOCTYPE html>")
(Of course you can apply more transformations like converting <br/> to <br> - it depends on your requirements.)
Even the related Google documentation recommends this approach (although they don't apply any transformations):
// return the snapshot
out.println(page.asXml());
I dont know the answer short of a switch on Page type and for XmlPage and SgmlPage one must do an innerHTML on the HTML element and manually write out the attributes. Not elegant and exact (its missing the doctype) but it works.
Page.getWebResponse().getContentAsString()
This is incorrect as it returns the text form of the original unrendered, no js bytes. If javascript executes and changes stuff, then this method will not see the changes.
page.asXml() will return the HTML. page.asText() returns it rendered down to just text.
Just want to confirm this only returns text within text nodes and does not include the tags and their attributes. If you wish to take the complete HTML this is not the good enuff.
Maybe you want to go with something like this, instead of using the HtmlUnit framework's methods:
try (InputStreamReader isr = new InputStreamReader(url.openConnection().getInputStream());
BufferedReader br = new BufferedReader(isr);){
String line ="";
String htmlSource ="";
while((line = br.readLine()) != null)
{
htmlSource += line + "\n";
}
return htmlSource;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Here is my solution that works for me:
ScriptResult scriptResult = htmlPage.executeJavaScript("document.documentElement.outerHTML;");
System.out.println(scriptResult.getJavaScriptResult().toString());

jsp to servlet communication with parameters from URL, not a form

I'm using netbeans to create a web application that allows a cell phone user to scan a QR code and retrieve a journal's previous/next title information. The take home point is that there's no form that the user will input data into. The QR code will contain the search string at the end of the URL and I want the search to start on page load and output a page with the search results. For now (due to simplicity), my model is simply parsing an XML file of a small sample of MARC records. Oh, to top it off...I'm brand new to programming in java and using netbeans. I have no clue about what javabeans are, or any of the more advance techniques. So, with that background explanation here's my question.
I have created a java class (main method) that parses my xml and retrieves the results correctly. I have an index.jsp with my html in it. Within the index.jsp, I have no problem using get to get the title information from my URL. But I have no clue how I would get those parameters to a servlet that contains my java code. If I manage to get the search string to the servlet, then I have no idea how to send that data back to the index.jsp to display in the browser.
So far every example I've seen has assumed you're getting form data, but I need parameters found, processed and returned on page load...IOW, with no user input.
Thanks for any advice.
Ceci
Just put the necessary preprocessing code in doGet() method of the servlet:
String foo = request.getParameter("foo");
// ...
request.getRequestDispatcher("/WEB-INF/page.jsp").forward(request, response);
And call the URL of the servlet instead of the JSP one e.g. http://example.com/page?foo=bar instead of http://example.com/page.jsp?foo=bar in combination with a servlet mapping on an URL pattern of /page/*.
You can get the url parameter in servlet using request.getParameter("paramName");
and you can pass the attribute to page from servlet using forwarding request from servlet to jsp.
See Also
Servlet wiki page
Bear in mind that your JSP page will compile internally to a servlet. So you can retrieve the string and print it back in the same JSP. For instance assuming you get the string in a parameter called param you would have something like this in your JSP:
<%
String param = request.getParameter( "param" );
out.println( "String passed in was " + param );
%>
One last thing, you mentioned the main method -- that only gets executed for stand alone applications -- whereas you're talking web/JSP :O

Categories