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
Related
I have a jsp code, where I fetch some JSON data from JAVA Class file. [Basically openfire users]
Now I get the data successfully, but I want to show this data in HTML table format.
How do I Do this ?
My JSP Code :
<%# page language="java" import="prov.*, java.util.*, java.io.*,java.text.*" contentType="text/html"%>
<%# page errorPage="error.jsp" %>
<%
Openfire tc = new Openfire();
tc.getUsers("192.168.50.218","epvFjHq5RHA614C7");
out.println("Data Is As Below : " + tc.getUsers("192.168.50.218","epvFjHq5RHA614C7"));
%>
And I get Response from the JAVA Class method like this :
[{"username":"abcd","name":"","properties":null},{"username":"admin","email":"admin#example.com","name":"Administrator","properties":null},{"username":"bizdd456d454mnc","email":"bizMNC#bizrtc.com","name":"bidzMNC","properties":null},{"username":"bizddd454mnc","email":"bizMNC#bizrtc.com","name":"bidzMNC","properties":null},{"username":"bizmnc","email":"admin#example.com","name":"511515151515151","properties":{"property":[{"#key":"console.order","#value":"session-summary=1"},{"#key":"console.rows_per_page","#value":"user-summary=8"}]}},{"username":"dhaval","email":"dhaval#bizrtc.com","name":"dhaval","properties":null},{"username":"keyur","email":"keyur#bizrtc.com","name":"keyur","properties":null},{"username":"minz","email":"bizMNC#bizrtc.com","name":"bidzMNC","properties":null},{"username":"patel","email":"rau#example.com","name":"patelbhai","properties":{"property":[{"#key":"console.order","#value":"session-summary=1"},{"#key":"console.rows_per_page","#value":"user-summary=8"}]}},{"username":"rajan","email":"rajan#bizrtc.com","name":"rajan","properties":null},{"username":"+username+","email":"+email+","name":"+name+","properties":null}]
As I am very new to JAVA and JSP I don't know how to parse this data to HTML Table.
So Please help.
You can see here how to do it. You can populate it in Javasript or jQuery, but it is better to use JSTL and not just call java code inside JSPs.
I would suggest you use mustache als template engine.
It allows you to use a HTML fragment as template (store it as resource) where double curly brackets (hence the name Mustache) denote the insertion points.
The full documentation of the Mustache syntax is here and a Java example here. Let us know how it is going.
I have a unique problem to solve. I need to dynamically create HTML based reports using a standard template. The contents of the report are created by a Java program so it makes sense to create a new class which uses JSP* to make a static HTML output file.
Here is the gist:
MyObject me = new MyObject();
me.process();
MyJSP jsp = new MyJSP(me);
File output = jsp.renderFrom("templateFile.jsp");
And output is a static, self contained HTML file which I can open in IE/Firefox and see the report.
What pattern/framework should I follow to allow me to best accomplish this?
Some notes: This is actually not a webapp. I am creating HTML based reports, but this won't be used as a webapp. I would also rather not use String.format(".. giant template string .. ", args) as this is very clumsy. I would much rather have a template file like this:
<html>
<head><title>First JSP</title></head>
<body>
<%
double num = Math.random();
if (num > 0.95) {
%>
<h2>You'll have a luck day!</h2><p>(<%= num %>)</p>
<%
} else {
%>
<h2>Well, life goes on ... </h2><p>(<%= num %>)</p>
<%
}
%>
<h3>Try Again</h3>
</body>
</html>
Where the "dynamic" aspects of the template can use MyObject properties, etc.
Lastly, I plan to use Java 7 for this due to some issues I am having with Java 8. If there is some better way to do this in Java 8, let me know...
*After some negative comments against JSP, perhaps JSP is not the right option. Some other library is fine too, as long as it works with Java.
Use a template engine for this!
I would recommend Freemarker, Velocity or StringTemplate. Just google it. Any of these engines will cover your needs.
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.
When I add a Filter to a particular JSP file, the Arabic characters in the output appears like ???, even when the page encoding is been set to UTF-8 by <% #page pageEncoding="UTF-8"%> and <% response.setCharacterEncoding("UTF-8");%>.
The strange thing is, before I added the Filter, the output of all Arabic pages appears with correct encoding. Can someone tell how this problem is caused and how I can solve it?
The filter is either directly or indirectly commiting the response and/or accessing the Writer or OutputStream of the HttpServletResponse which causes that the encoding cannot be changed anymore in the JSP. Fix the code in the filter accordingly. The filter should in any way not be writing anything to the response body. There the JSP (for HTML) or Servlet (for other content) is for.
By the way, you don't need to call <% response.setCharacterEncoding("UTF-8");%>. The <%#page pageEncoding="UTF-8"%> already implicitly does that.
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.