I've a Servlet that makes and returns a zip file
Something like this
response.setHeader("Pragma","Public");
response.setHeader("Cache-Control","must-revalidate,post-check=0,pre-check=0");
response.setContentType("application/octet-stream");
response.setHeader("Expires", "0");
response.setHeader("Content-Transfer-Encoding", "binary");
if(file.getName().contains("–")){
response.setHeader("Content-Disposition", "inline; filename=\"file.zip\"");
}
OutputStream os = response.getOutputStream();
ZipOutputStream zos = new ZipOutputStream(os);
for (File f : files) {
//add files, it's working...
}
bis.close();
fis.close();
zos.closeEntry();
}
zos.flush();
zos.close();
os.flush();
os.close();
Currently to download I'm using a iframe, so I set src attribute to start download.
The download frame loads when call this function
function loadIDownloadFrame(url) {
document.getElementById("idownloadFrame").src=url;
}
But now, I need show a message after return the zip file without leaving current page. I need to know if the servlet returned the zip file.
I tried get iframe status with "window.frames['idownloadFrame'].document.readyState", but always status is "complete".
Anyone have any solutions?
I think you could directly refer to download link to mapped Servlet(which returns the downloadable binary). It would not change the page if you set appropriate header in the mapped servlet to return the binary, from the code snippet it looks like you are doing that already. Why do you have to have file download in a different iframe? You don't necessarily need that.
Where do you have to show the message? Like a JavaScript alert or something?
Related
EDIT: The data I wanna send is in an rds. I fetch that into an output stream and then try to send it over as a pdf to the user.
The file gets generated but on opening the browser shows 'Failed to load PDF document.'
I have read that setting the ContentType to "application/pdf" helps but it does not in my case. The code is given below
byte[] b = generateFileService
.getDeviceHumidityRecordByPeriod(deviceIdValue, parseUnixTimestamp(startTime), parseUnixTimestamp(endTime));
OutputStream output = response.getOutputStream();
response.setContentType("application/pdf");
response.addHeader("Content-disposition", "attachment;filename=test.pdf");
output.write(b);
output.close();
response.flushBuffer();
}
if I change the file name to test.csv and then use content type as txt/plain, it works perfectly and a csv file is written.
I used Apache PDFBox to write data into a pdf file. The page offset needs to be tracked to add pages dynamically. Then you can convert the pdf into bytes and send it to the client by specifying response.setContentType("application/pdf") and response.addHeader("Content-disposition", "attachment;filename=test.pdf")
I am using java and struts. I have a scenario where there is 'Download' link in the page. After clicking on this link the control goes to the Action class, where I have String content which I need to write to a .txt file and then download that txt file.
Eventually whenever we click on the download link, we should be able to download a txt file having content a particular string.
I used below piece of code,
FileOutputStream outputStream = new FileOutputStream(fileNameWithDirectory);
outputStream.write(fileContentString.getBytes());
outputStream.close();
ActionForward forward = new ActionForward("doc/" + filename);
forward.setName(filename);
forward.setRedirect(true);
return forward;
Also I tried with FileWriter in place of FileOutputStream like,
FileWriter fileWriter = new FileWriter(fileNameWithDirectory);
fileWriter.write(fileContentString);
fileWriter.flush();
fileWriter.close();
But always instead of downloading the txt file, the control opens a new window where the String content is written.
Please suggest me, how would I able to download that .txt file.
You should add Content-Disposition: attachment to say browser, that it should download the file, not to open it.
See more details here
Also Struts has DownloadAction, you may use it as well.
You don't need to write the file and then redirect to it. You can set a http response header called Content-Disposition and then print your data into the http response body.
use it like this
response.addHeader("Content-Disposition", "Content-Disposition: attachment; filename=\""+filename+"\"");
of course this depends on which technology stack you're using.
Convert your text file to stream. and set content type as you wanted to download.
response.setContentType("application/pdf");
try {
// get your file as InputStream
InputStream is = ...;
// copy it to response's OutputStream
org.apache.commons.io.IOUtils.copy(is, convertedTextFiletoStream);
} catch (IOException ex) {
log.info("Error writing file to output stream. Filename was '{}'", fileName, ex);
throw new RuntimeException("IOError writing file to output stream");
}
I have created the zip file (sample.zip) which has some files with no issues. When I open the sample.zip, it contains the file which expected.
I want to put that zip file into http response. Currently I am using the following:
response.setContentType("application/zip");
response.addHeader("Content-Disposition", "attachment; filename="+"sampleZip.zip");
response.setContentLength(2048);
response.setHeader("Set-Cookie", "fileDownload=true; path=/");
FileInputStream fileInputStream = new FileInputStream("sample.zip");
OutputStream responseOutputStream = response.getOutputStream();
int bytes;
while ((bytes = fileInputStream.read()) != -1) {
responseOutputStream.write(bytes);
}
response.flushBuffer();
Now its download the zip file in my browser default download location. But when I open that zip file it showing
Cannot open file: it does not appear to be valid archive
Kindly help me to fix this please.
This code looks good to me. But you are setting a default content length which might be the issue. Create File instanceand use the file.length() method to set the content length ans use the same file for your input stream. Also reading byte by byte is not a good idea. If possible use apache's IOUtils.copy() to copy data from your input stream to the ServletOutputStream.
In my project (Java SpringMVC3) I get an XLS file via HttpClient and I want that file to be downloaded like it's a real download. A popup window showing download dialog.
How can I do that?
Controller should copy the content of file to response object. Do not forget - controller function must return NULL. Below I show a working example from my application:
String filename = /* path to a file */
File file = new File(filename);
response.setContentType(new MimetypesFileTypeMap().getContentType(file));
response.setContentLength((int)file.length());
response.setHeader("content-disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
InputStream is = new FileInputStream(file);
FileCopyUtils.copy(is, response.getOutputStream());
return null;
Basically you need to implement a Controller that takes care of the download and specify the response's header-mime type. then you invoke that Controller from the view.
Here is a short example how to specify a header-mime type
HTTP Header Mime Type in Websphere Application Server 7
<%
response.reset();
response.setHeader("Content-Disposition", "attachment;filename=\"" + "test.xls\"");
response.setHeader("Content-Transfer-Encoding", "binary");
response.setContentType("application/vnd.ms-excel");
InputStream is = new FileInputStream(realPath);
//OutputStream outStream = response.getOutputStream();
JasperPrint jasperPrint = JasperFillManager.fillReport(is,
parameters, new JRBeanCollectionDataSource(pdfList));
JRAbstractExporter exporter = new JExcelApiExporter();
exporter.setParameter(JExcelApiExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JExcelApiExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
exporter.setParameter(JExcelApiExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
exporter.setParameter(JExcelApiExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
exporter.setParameter(JExcelApiExporterParameter.OUTPUT_STREAM, out);
exporter.exportReport();
outStream.flush();
outStream.close();
out.clear();
out =pageContext.pushBody();
%>
we use the code above to generate an excel, and it works well in tomcat + windows, but after we upload to linux + weblogic server, the excel is corrupted. I use text editor to open the excel, I found it add several empty line in the excel, which caused the excel can not be open successfully, anyone can point me the right direction ? Why there are space ? How it comes ?
Thanks in advance !
I suspect that your use of pageContext.pushBody() may be the culprit.
pushBody is, as far as I know, meant for updating the output in the scope of a JSP tag.
When you are generating binary content such as an excel file, where you need to be absolutely sure that the intended bytes, and only the intended bytes reach the browser, you need to write those bytes, flush the output, and then make sure that nothing else gets written. By invoking pushBody(), you are making it so that more content can be written to the output, and any blank lines (and the carriage returns / line feeds between them) in the JSP page could be output.
All in all, I suggest that you just not do this in a JSP - do it in a Servlet instead.