my problem: i have a jsp where a button press will send a ID to the servlet.
with the iD, my Servlet will send it further to a method, to use a sql statement to fetch data from the database base on the id.
it all works fine, even the chart.
but now i want to include the chart back to my jsp and let the user see it without changing sites. with the outputstream it will stay on the servlet, and if i want to change my data, i need to go back.
i tried going for the saveasPng route, but java always say that path was not found.
any help is appreciated.
OutputStream outputStream = response.getOutputStream();
response.setContentType("image/png");
int width = 500;
int height = 350;
ChartUtilities.writeChartAsPNG(outputStream, chart, width, height);
// try {
// final ChartRenderingInfo info = new
// ChartRenderingInfo(new StandardEntityCollection());
//
// final File file1 = new File(request.getContextPath() + "WebContent/images/piechart.png");
// ChartUtilities.saveChartAsPNG(
// file1, chart, 600, 400, info);
// System.out.println("hallo TRue");
// } catch (Exception e) {
// e.printStackTrace();
// }
request.setAttribute("imagePath", request.getContextPath() + "/WebContent/images/piechart.png");
request.setAttribute("chart", chart);
//request.getRequestDispatcher("Diagramm.jsp").forward(request, response);
I see two different approaches here:
Add JavaScript to your JSP page and using AJAX patterns to invoke your servlet and modify dynamically the content of the JSP page within the browser with the result.
Refresh your JSP page adding a static HTML IMG tag where you invoke the servlet with the new ID parameter within the SRC attribute of the IMG tag. Something like <IMG src="/MyServlet?ID=xxx" width="500" height="350">
Related
I have written restful webservice which will return PDF file and this PDF will be appearing in IFrame in browser.
This part is good going.
But, the thing on which I am facing difficulties is, PDF file is opening on browser with selected zoom vale 'Automatic Zoom' but I wanted to show this PDF with zoom value 'Page Width' selected.
Please find below method which return PDF.
/**
* #param file
* #return Response object.
*/
private Response processRequest(final String filePath)
{
File file = new File(filePath);
PDPageFitDestination dest = new PDPageFitDestination();
PDActionGoTo action = new PDActionGoTo();
action.setDestination(dest);
ByteArrayOutputStream output = new ByteArrayOutputStream();
PDDocument pd=null;
try
{
pd = PDDocument.load(file);
pd.getDocumentCatalog().setOpenAction(action);
pd.save(output);
}
catch(IOException e)
{
e.printStackTrace();
}
catch(COSVisitorException e)
{
e.printStackTrace();
}
//ResponseBuilder responseBuilder = Response.ok((Object)file);
ResponseBuilder responseBuilder = Response.ok(output.toByteArray());
responseBuilder.header("Content-Type", "application/pdf; filename=return.pdf");
responseBuilder.header("Content-Disposition", "inline");
return responseBuilder.build();
}
I think by providing any header value specific to zoom value will return PDF with zoom value 'Page Width' but not getting which header related to it.
Please provide your suggestions in this regard.
I solved my problem. Just I needed to use pdf specific parameters in request URL. For detail go to PDFOpenParameters
I want to write some data to a csv file and user should be able to download it through browser.
#Actions({ #Action(value = "/downloadReport", results = { #Result(name = "success", type = "stream", params = {
"contentType", "${type}", "inputName", "stream", "bufferSize","2048", "contentDisposition",
"attachment;filename=\"${filename}\"" }) }) })
#SkipValidation
public String downloadReport() throws BaseAppException {
try {
filename =AdSkippingConstants.REPORT_FILE_NAME;
type = AdSkippingConstants.CSV_FILE_TYPE;
File file = new File(filename);
FileUtils.write(file, "Helloo World");
stream = new FileInputStream(file);
}
catch (IOException e) {
logger.error("Error occured while exporting error data", e);
}
return SUCCESS;
}
In jsp i am using ajax call
function exportAsCSV(){
$.ajax({
url: 'downloadReport.action?',
type: "POST",
success: function() {
//To Un Block the Change Password page if the page reloaded
//$('div.ui-dialog').unblock();
// $('#change_password_details_body').html(data);
},
error: function(){
//To Un Block the Change Password page if the page reloaded with error.
//$('div.ui-dialog').unblock();
}
});
}
I am able to get the response and even fileDownload=true is coming in response but still download to csv option is not opening in any browser and also please let me know how to pass html data to action for writing to csv.
In jsp i am using this code to do ajax call
var gridModel = "gridModel";
var sortname = "1";
var sortorder = "asc";
var caption = '<s:text name="grid.label.heading" />';
var url = "getGridSearchResults.action";
init.push(function() {
loadTable("gridtable", url, gridModel, columnDefs, columns, sortname,
sortorder, caption);
});
<table cellpadding="0" cellspacing="0" border="0" class="table table- striped table-bordered" id="gridtable"></table>
So with ajax call i am loading the data for the table.
You don't need AJAX. This is a common misconception.
You simply need to perform a call to an action returning a stream result, with a contentDisposition: attachment HTTP header.
This will tell the browser to download the file instead of opening it inline.
Read more in this answer
EDIT: if you need to send data from an HTML table to the action, you need to
use hidden input fields having the same value that you printed with <s:property/> tags (or whatever);
specify an index with the list[%{#status.index}].attribute notations to post the different records as different elements of a Collection.
I have done it using :
ActionContext.getContext().getSession().put("RESULTS_GRID", searchResultsForDownload);
and then retrieving the list in my DownLoadAction for getting the data and writing to csv using BufferedWriter.
I got the following to work already:
User can upload a file (i.e. a compressed archive)
User can uncompress the file on the server
User can execute some stuff on these files, which results in more files to be generated
Now I need to get step 4 to work:
User can download the files to his own computer again
Can anyone give me a hint? I tried to understand the stuff I found on Google, but it does not work quite as expected. Do I have to set a content type? When I set application/octet stream only txt and csv files would display correctly (in the browser, not as download popup as I wanted) other files would not work...
JSP:
<a4j:commandLink value="Download" action="#{appController.downloadFile}" rendered="#{!file.directory}">
<f:param name="file" value="#{file.absoluteFilename}" />
</a4j:commandLink>
appController:
public String downloadFile() {
String filename = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("file");
File file = new File(filename);
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
writeOutContent(response, file, file.getName());
FacesContext.getCurrentInstance().responseComplete();
return null;
}
private void writeOutContent(final HttpServletResponse res, final File content, final String theFilename) {
if (content == null) {
return;
}
try {
res.setHeader("Pragma", "no-cache");
res.setDateHeader("Expires", 0);
res.setHeader("Content-disposition", "attachment; filename=" + theFilename);
FileInputStream fis = new FileInputStream(content);
ServletOutputStream os = res.getOutputStream();
int bt = fis.read();
while (bt != -1) {
os.write(bt);
bt = fis.read();
}
os.flush();
fis.close();
os.close();
} catch (final IOException ex) {
Logger.getLogger(ApplicationController.class.getName()).log(Level.SEVERE, null, ex);
}
}
Your concrete problem is that you're attempting to download files by Ajax. This is not correct. JavaScript can't deal with binary responses nor has it any facilities to force a Save As dialogue. You need to make it a normal synchronous request instead so that it's the webbrowser itself who has to deal with it.
<h:commandLink value="Download" action="#{appController.downloadFile}" rendered="#{!file.directory}">
<f:param name="file" value="#{file.absoluteFilename}" />
</h:commandLink>
As to setting the content type, if you have a file name with extension at your hands, you could use ServletContext#getMimeType() to resolve it based on <mime-mapping> in web.xml (either the server's default one or your webapp's one).
ServletContext servletContext = (ServletContext) externalContext.getContext();
String contentType = servletContext.getMimeType(file.getName());
if (contentType == null) {
contentType = "application/octet-stream";
}
response.setContentType(contentType);
// ...
(note that I assume that you're using JSF 1.x, seeing the way how you obtained the servlet response, you could since JSF 2.x otherwise also use ExternalContext#getMimeType())
I have done the step 4 some weeks ago, and let me give you some advices:
Use a link html tag component. For this, I recommend the a4j:htmlCommandLink tag component (it's like the common h:commandLink with the difference that the <f:param /> components are always rendered, you can check more in the component documentation).
If you don't know the type of the file to download (), then you must set the Content as application/octet-stream.
After setting up the file to download to your response, you should set that the response has been completed.
I'll put my Backing Bean code for this request:
public void descargaArchivo() {
//sorry but the programming standard says that we MUST declare
//our variables at the beginning of any function =(
HttpServletResponse objResponse;
FileInputStream objFileInputStream;
String strNombreCompletoArchivo, strNombreArchivo;
byte[] arrDatosArchivo;
try {
//Here I get the <f:param> with the full name of the file. It encapsulates
// the Faces.getCurrentInstance... call.
strNombreCompletoArchivo = UManejadorSesionWeb.obtieneParametro("nombreCompletoArchivo");
//The function obtieneNombreArchivo retrieves the name of the file
//based on the full name and the file separator (/ for Windows, \ for Linux)
strNombreArchivo = UFuncionesGenerales.obtieneNombreArchivo(strNombreCompletoArchivo);
//Getting the response from Faces.getCurrentInstance...
objResponse = UManejadorSesionWeb.obtieneHttpResponse();
//Setting up the response content type and header (don't set the length!)
objResponse.setContentType("application/octet-stream");
objResponse.setHeader("Content-Disposition", "attachment; filename=\"" + strNombreArchivo + "\"");
//Create the FileInputStream for the file to download
objFileInputStream = new FileInputStream(strNombreCompletoArchivo);
//Setting the file on the response
arrDatosArchivo = new byte[UConstante.BUFFER_SIZE];
while(objFileInputStream.read(arrDatosArchivo, 0, UConstante.BUFFER_SIZE) != -1) {
objResponse.getOutputStream().write(arrDatosArchivo, 0, UConstante.BUFFER_SIZE);
}
objFileInputStream.close();
objResponse.getOutputStream().flush();
objResponse.getOutputStream().close();
//Telling the framework that the response has been completed.
FacesContext.getCurrentInstance().responseComplete();
} catch (Exception objEx) {
//manage the errors...
}
}
//The constant used for byte array size
public class UConstante {
public static final int BUFFER_SIZE = 2048;
}
The jsp fragment I used looks like this:
<a4j:htmlCommandLink rendered="#{documento.rutaDestino != null}"
action="#{documentoRequerido.descargaArchivo}">
<f:param name="nombreCompletoArchivo" value="#{documento.rutaDestino}" />
<h:graphicImage value="/Resource/iconos/mover-abajo.png" styleClass="pic" />
</a4j:htmlCommandLink>
Hope this helps you.
EDIT: I had some spare time, sorry but we are kinda busy in the project. The Java code was updated and tested in IE8, Firefox 9 and 10, and Chrome 16. For the value of buffer size constant, I did some research and found a good answer in this site.
P.S.: I don't take this as a competition, I just try to help people when I can. If my code is not good then thanks for letting me know it, that's the better way for everyone to grow better and healthy :).
EDIT: Thanks to #lisa
To achieve the following manually, just changing this part in the snippet
//strNombreCompletoArchivo = UManejadorSesionWeb.obtieneParametro("nombreCompletoArchivo");
String parameterStr = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap.get("nombreCompletoArchivo");
strNombreCompletoArchivo = parameterStr;
You don't need the richfaces a4j:commandLink tag for the download, the standard jsf tag h:commandLink would be enough.
Then make sure you have the following headers set on your response (you can check with firebug in firefox):
Content-Disposition attachment; filename="your_file_name.xxx"
Content-Type application/xxx
Content-Length 1234
Content-Length: number of bytes.
what's the best approach to read an image via URL and render it on a JSP page?
so far, I've coded two JSP pages.
EDIT START:
*Experimental: Obviously the ImageServ will be a servlet, not a jsp.
EDIT END:
index.jsp
<%page ....
<html>
......
<img src="ImageServ.jsp?url=http://serveripaddress/folder/image.jpg" />
.....
ImageServ.jsp
<%#page import="javax.imageio.ImageIO"%>
<%#page import="java.net.URL"%>
<%#page import="java.io.*, java.awt.*, java.awt.image.*,com.sun.image.codec.jpeg.*" %>
<%
try {
String urlStr = "";
if(request.getParameter("url") != null)
{
urlStr = request.getParameter("url");
URL url = new URL(urlStr);
BufferedImage img = null;
try{
img = ImageIO.read(url);
out.println(" READ SUCCESS" + "<br>");
}catch(Exception e) {
out.println("READ ERROR " + "<br>");
e.printStackTrace(new PrintWriter(out));
}
try {
response.setContentType("image/jpeg");
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(response.getOutputStream());
encoder.encode(img);
}catch(Exception ee) {
response.setContentType("text/html");
out.println("ENCODING ERROR " + "<br>");
ee.printStackTrace(new PrintWriter(out));
}
}
} catch (Exception e) {
e.printStackTrace(new PrintWriter(out));
}
%>
But this doesn't seem to be working:
all the time i see this error:
READ SUCCESS
ENCODING ERROR
java.io.IOException: reading encoded JPEG Stream
at sun.awt.image.codec.JPEGImageEncoderImpl.writeJPEGStream(Native Method)
at sun.awt.image.codec.JPEGImageEncoderImpl.encode(JPEGImageEncoderImpl.java:476)
at sun.awt.image.codec.JPEGImageEncoderImpl.encode(JPEGImageEncoderImpl.java:228)
Any ideas on how to get this working???
Your image data is already encoded so you can simply write it: ImageIO.write(img, "jpeg", response.getOutputStream());. You don't need to (and can't) use JPEGImageEncoder.
Classic question. Here's an example: http://www.exampledepot.com/egs/javax.servlet/GetImage.html
Also, don't do all that coding in a JSP - keep that for front-end rendering coding only; do the Java coding in a backend class.
Terrible and awful code. NEVER EVER write controller logic in a JSP that's why I have JSP to the guts. You cannot write binary data to a JSP output stream. The stream has already been initialized for text output. Put your logic in a servlet and pipe the input stream to the response output stream with Commons IO. This will work. If you still insist on that crappy solution, you will need to write a filter which completely wraps the response and serves binary data instead. See this for reference and examine its code. Good luck.
Edit:
doGet(...) {
response.setContentType("image/jpeg");
String url = request.getParameter("url");
...
InputStream is = ....getInputStream();
IOUtils.copy(is, response.getOutputStream());
// cleanup
} // done
This is how I pipe PDF from local disk but there is no difference to serving from a URL.
I'm trying to send an image url to the browswer using javascript and servlet.
I'm doing the following
In html :
<script type="text/javascript" src="../licenta/WebRoot/Scripts/choosebanner.js"></script>
In javascript :
window.onload = Onload;
function OnLoad()
{
var requestURI = window.location;
var resolution = screen.width + 'x' + screen.height;
var colorDepth = screen.colorDepth;
var query = '?requestURI=' + encodeURIComponent(requestURI)
+ '&resolution=' + encodeURIComponent(resolution);
document.getElementById("body").innerHTML = "<img src ='http://dan-vaio:8080/licenta/ bannerimg.gif'" + query + " width = 500 height = 200 />";
}
in servlet:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
String requestURI = request.getParameter("requestURI");
String resolution = request.getParameter("resolution");
response.setContentType("text/html; charset=UTF-8");
String img = "http://dan-vaio:8080/licenta/advertiser/banners/leader.jpg";
PrintWriter out = response.getWriter();
out.print(img);
out.close();
}
The problem is that i can't get the image to be displayed. Javascript works fine, calls the server, the servers prints the respsone, but the jpg isn't showed in the html page.Any hints on how to get this working ?
Thanks a lot
I think you want to deliver the image itself, not its path. Read the image file in the servlet and write the binary to the response. Another way would be to set the src in the javascript to the response of the servlet. But then you need an Ajax call to the servlet, read the response and write it in the img src tag. The way you are doing it, you point the img src to a string and that of course won't display an image.
It's about your content type. You should set the content type of the response to image/jpeg. This way your navigator will understand that it's an image. You should change it like this :
response.setContentType("image/jpeg");
That's if you're serving jpeg images, Otherwise please follow this like to find your convenient content type : http://www.w3schools.com/media/media_mimeref.asp
Steps:
You need to convert image to FileInputStream.
Then set response.setContentType("image/jpeg");
Example:
FileInputStream fileIS = new FileInputStream("sample.jpg");
response.setContentLength(fileIS.available());
int i = 0;
while ((i = fileIS.read()) != -1) {
out.write(i);
}
fileIS.close();