I am generating csv in my code, It takes some time to generate. So, I am sending an email with link once the csv file is generated. When I click that, getting 404 not found error. When I have the same link in the html, I am able to download it. Any insight or sample to refer
Sample Link -http://localhost:9090/api/report/file?fileName=filename.csv
Java code to download the report
#RequestMapping(value = "api/report/file")
public void downloadCSV(HttpServletResponse response, #RequestParam("fileName") String fileName) throws IOException {
File file = new File(fileName);
InputStream is = new FileInputStream(file);
response.setContentType("application/octet-stream");
// Response header
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
// Read from the file and write into the response
OutputStream os = response.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
os.flush();
os.close();
is.close();
}
Add GET method to this mapping: #RequestMapping(value = "api/report/file")
Related
I have a process in a servlet that creates a .pdf file and sends it to the client. However, Adobe won't open the downloaded file ("There was an error opening this document. The file is damaged and could not be repaired."). The original created file residing on the server is fine and Adobe doesn't have a problem opening it.
My code:
private static void sendFile(HttpServletResponse response, String pdfPath) throws FileNotFoundException, IOException {
PrintWriter out = response.getWriter();
File f = new File(pdfPath);
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Content-Disposition", "attachment; filename=\"" + f.getName());
response.setContentLength((int) f.length());
response.setContentType("application/pdf");
FileInputStream fileInputStream = new FileInputStream(pdfPath);
int i;
while ((i = fileInputStream.read()) != -1) {
out.write(i);
}
fileInputStream.close();
out.close();
}
A Writer writes characters, not bytes.
Use the response output stream.
And don't read and write byte by byte, especially from a FileInputStream.This is extremely inefficient. Just use Files.copy().
File getting downloaded successfully but I cannot open file, it seems to be corrupted.Not sure what I am missing.
public StreamingResponseBody getStreamingFile() throws IOException {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=\"discrepancyReport.xls\"");
InputStream inputStream = new FileInputStream(new File(rootPath + ".xlsx"));
return outputStream -> {
int nRead;
byte[] data = new byte[4096];
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
outputStream.write(data, 0, nRead);
}
inputStream.close();
};
Issue seems to be with swagger.When I tried hitting end-point directly, It is working as expected.
I have a servlet to let user download a file from server. The original file is human readable, but the downloaded file alwyas contains binary content at the end of the file.
HttpSession session = request.getSession(true);
String fileName = session.getAttribute("download").toString();
System.out.println("Download file " + fileName);
File file = new File(fileName);
FileInputStream fileIn = new FileInputStream(file);
response.setContentType("text/plain");
response.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
ServletOutputStream out = response.getOutputStream();
byte[] bytes = new byte[BYTES_DOWNLOAD];
while (fileIn.read(bytes, 0, BYTES_DOWNLOAD) != -1) {
out.write(bytes, 0, BYTES_DOWNLOAD);
}
out.flush();
out.close();
Thanks in advance.
Small bug in your code:
byte[] bytes = new byte[BYTES_DOWNLOAD];
int count;
while ( (count = fileIn.read(bytes)) != -1) {
out.write(bytes, 0, count);
}
What binary content do you see? Is it perhaps the line endings in the file, if any?
hi i have tried the following java codes which works fine if i use them as a java application but when i use the same code in my servlet page they dont work means i am not able to download the files. Please suggest what changes should i do so that i can download the file using Servlets.
a.
java.io.BufferedInputStream in = new java.io.BufferedInputStream(new java.net.URL("http://169.254.174.150:8084/WebApplication1/files/check.txt").openStream());
File f1 = new File("D:\\a.txt");
java.io.FileOutputStream fos = new java.io.FileOutputStream(f1);
java.io.BufferedOutputStream bout = new BufferedOutputStream(fos, 1024);
byte data[] = new byte[1024];
while (in.read(data, 0, 1024) >= 0) {
bout.write(data);
}
bout.close();
in.close();
}
b. http://www.javabeat.net/examples/2012/04/13/download-file-from-http-https-server-using-java/
One of the older JavaBeat examples like the one you specified can be found here
I found other solutions too but this seems to be the most comprehensive.
Couple of things, insetad of writing it to a file try wrting the data directly to the responce. Before writing data you will have to set the following parameters to the responce
//byte[] filedata = ; intialize your file contents
String filename = "a.txt";
// set the header information in the response.
res.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\";");
res.setContentType("application/x-unknown");
ByteArrayInputStream byteStream = new ByteArrayInputStream(filedata);
BufferedInputStream bufStream = new BufferedInputStream(byteStream);
ServletOutputStream responseOutputStream = res.getOutputStream();
int data = bufStream.read();
while (data != -1)
{
responseOutputStream.write(data);
data = bufStream.read();
}
bufStream.close();
responseOutputStream.close();
where res is a HttpServletResponse object. After this you can write data to responseOutputStream.
I m using content-disposition to download pdf . When I click the download button, the complete pdf file is downloaded first and then browser shows the dialog box to save the file. I want the browser to show the process of downloading. The following is my servlet code:
String filename = "abc.pdf";
String filepath = "/pdf/" + filename;
resp.setContentType("application/pdf");
resp.addHeader("content-disposition", "attachment; filename=" + filename);
ServletContext ctx = getServletContext();
InputStream is = ctx.getResourceAsStream(filepath);
System.out.println(is.toString());
int read = 0;
byte[] bytes = new byte[1024];
OutputStream os = resp.getOutputStream();
while ((read = is.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
System.out.println(read);
os.flush();
os.close();
}catch(Exception ex){
logger.error("Exception occurred while downloading pdf -- "+ex.getMessage());
System.out.println(ex.getStackTrace());
}
The progress cannot be determined without knowing the response body's content length beforehand in the client side. To let the client know about the content length, you need to set the Content-Length header in the server side.
Change the line
InputStream is = ctx.getResourceAsStream(filepath);
to
URL resource = ctx.getResource(filepath);
URLConnection connection = resource.openConnection();
response.setContentLength(connection.getContentLength()); // <---
InputStream is = connection.getInputStream();
// ...
Unrelated to the concrete problem, your exception handling is bad. Replace the line
System.out.println(ex.getStackTrace());
by
throw new ServletException(ex);