I have a requirement to download excel to the excel file on client side using servlet. I am first creating an excel by fetching the values from mysql table and then downloading it. The excel is getting created in the path provided but I am unable to download it. Please find my code below for downloading:
String exportFileName = ResourceConstants.EXCEL_FILEPATH+"/"+ResourceConstants.EXCEL_FILENAME;
FileInputStream inf = null;
response.setContentType("application/vnd.ms-excel");
response.addHeader("content-disposition",
"attachment; filename=" + exportFileName);
response.setHeader("Pragma", "public");
response.setHeader("Cache-Control", "no-store");
response.addHeader("Cache-Control", "max-age=0");
final int size = 1024;
try{
inf = new FileInputStream(exportFileName);
response.setContentLength(inf.available());
final byte[] buffer = new byte[size];
ServletOutputStream os = null;
os = response.getOutputStream();
int length = 0;
while ((length = inf.read(buffer)) != -1) {
os.write(buffer, 0, length);
}
inf.close();
os.flush();
os.close();
} catch (final FileNotFoundException e) {
LOGGER.error("FileNotFoundException occurred in download excel method!!!"+e.getMessage());
}
Please help me understand if I am doing something wrong here.
Related
I am using Tomcat 8 and I have functionality to download large files from tomcat server places in context docbase folder.
Below is the piece of code I am using the file to download:
PrintWriter out = response.getWriter();
response.setContentType("APPLICATION/OCTET-STREAM");
response.setHeader("Content-Disposition",
"attachment; filename=filename);
FileInputStream fileInputStream = new FileInputStream("filepath");
int i;
while ((i=fileInputStream.read()) != -1) {
out.write(i);
}
fileInputStream.close();
out.close();
When I download a file it is downloading with a speed of 65KB/sec
from the save server. If I place the same file in Apache server and try to download the download speed is 135KB/sec.
Could someone help me speed up the file download from Tomcat?
The problem is that reading and writing a byte at a time to unbuffered streams is very inefficient. Looking at this previous answer and adapting it to your code, we could use:
// Assume ServletResponse response
ServletOutputStream servletOutputStream = response.getOutputStream();
response.setContentType("APPLICATION/OCTET-STREAM");
response.setHeader("Content-Disposition",
"attachment; filename=filename);
FileInputStream fileInputStream = new FileInputStream("filepath");
// Choose a bigger value if you want
byte[] buffer = new byte[4096];
int n;
while ((n = fileInputStream.read(buffer) != -1)
{
servletOutputStream.write(buffer, 0, n);
}
fileInputStream.close();
servletOutputStream.close();
The above should be very efficient and hopefully equal or surpass your reported Apache speeds.
Need a servlet to download a file from path like /home/Bureau.. in jee gwt
I used this but isn't work
and I went to download all file's type image
String filePath = request.getParameter("file");
String fileName = "test";
FileInputStream fileToDownload = new FileInputStream(filePath);
// ServletOutputStream output = response.getOutputStream();
response.setHeader("Content-Type", "image/png");
//response.setContentType("image/png");
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + ".png\"");
// response.setContentLength(fileToDownload.available());
int readBytes = 0;
byte[] buffer = new byte[10000];
while ((readBytes = fileToDownload.read(buffer, 0, 10000)) != -1) {
//output.write(readBytes);
response.getOutputStream().write(readBytes);
}
response.getOutputStream().close();
fileToDownload.close();
fileToDownload.close();
The problem is at below line where you are writing no of bytes not actual bytes. Here readBytes represents no of bytes read at a time where as buffer contains actual bytes that is read.
response.getOutputStream().write(readBytes);
Try
OutputStream outputStream = response.getOutputStream();
while ((readBytes = fileToDownload.read(buffer)) != -1) {
outputStream.write(buffer,0,readBytes);
}
outputStream.close();
I suggest you to call response.getOutputStream() single time.
Your code will give you IndexOutOfBoundsException if the size of the file is less than 10000 bytes because of below line
fileToDownload.read(buffer, 0, 10000)
Change it to
fileToDownload.read(buffer)
Use ServletContext to get file path.
ServletContext context = getServletContext();
For more info have a look at below posts:
Writing image to servlet response with best performance.
How do I return an image from a servlet using ImageIO?
I want to make a provision to download all file types...Is there any way to download any file format in jsp...
My code snippet:
String filename = (String) request.getAttribute("fileName");
response.setContentType("APPLICATION/OCTET-STREAM");
String disHeader = "Attachment";
response.setHeader("Content-Disposition", disHeader);
// transfer the file byte-by-byte to the response object
File fileToDownload = new File(filename);
response.setContentLength((int) fileToDownload.length());
FileInputStream fileInputStream = new FileInputStream(fileToDownload);
int i = 0;
while ((i = fileInputStream.read()) != -1) {
out.write(i);
}
fileInputStream.close();
If I specify setContentType as APPLICATION/OCTET-STREAM, pdf, text, doc files are getting downloaded.... But the problem is with image files...
What is problem with image files? I want to download all image file types...
I searched similar questions but could not find proper answer...
Thanks...
Finally I somehow managed to do this...
The problem is with JSP's "Out.write", which is not capable of writing byte stream...
I replaced jsp file with servlet...
The code snippet is:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String filename = (String) request.getAttribute("fileName");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment;filename="+filename);
File file = new File(filename);
FileInputStream fileIn = new FileInputStream(file);
ServletOutputStream out = response.getOutputStream();
byte[] outputByte = new byte[(int)file.length()];
//copy binary contect to output stream
while(fileIn.read(outputByte, 0, (int)file.length()) != -1)
{
out.write(outputByte, 0, (int)file.length());
}
}
Now I can download all types of files....
Thanks for the responces :)
Check the following link ,
JSP download - application/octet-stream
Might help you to resolve the issue.
for images you should use setContentType(image/jpg).you can checkout this link for mime types
http://webdesign.about.com/od/multimedia/a/mime-types-by-content-type.htm
i have a project where i'm dealing with restful web service, especially need to return images for android client, when client is entering the "gallery" he need to get a root collection which have to return all of folders and file(images) from static folder on running server. Can someone help with this? How can i return images that could be accessed by client for detailed view?
You only need to getHttpServletRequest and HttpServletResponse type of object and apply below code -
String filePath = request.getParameter(YOUR_FILE_PATH_PARAMETER");
String filePath = filePath;
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename="
+ "YOUR_FILE_NAME");
// Get it from file system
FileInputStream in = new FileInputStream(new File(filePath));
ServletOutputStream out = response.getOutputStream();
byte[] outputByte = new byte[4096];
// copy binary content to output stream
while (in.read(outputByte, 0, 4096) != -1) {
out.write(outputByte, 0, 4096);
in.close();
out.flush();
out.close();
This question already has answers here:
Simplest way to serve static data from outside the application server in a Java web application
(10 answers)
Closed 2 years ago.
How should I implement simple file download servlet?
The idea is that with the GET request index.jsp?filename=file.txt, the user can download for example. file.txt from the file servlet and the file servlet would upload that file to user.
I am able to get the file, but how can I implement file download?
Assuming you have access to servlet as below
http://localhost:8080/myapp/download?id=7
I need to create a servlet and register it to web.xml
web.xml
<servlet>
<servlet-name>DownloadServlet</servlet-name>
<servlet-class>com.myapp.servlet.DownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DownloadServlet</servlet-name>
<url-pattern>/download</url-pattern>
</servlet-mapping>
DownloadServlet.java
public class DownloadServlet extends HttpServlet {
protected void doGet( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getParameter("id");
String fileName = "";
String fileType = "";
// Find this file id in database to get file name, and file type
// You must tell the browser the file type you are going to send
// for example application/pdf, text/plain, text/html, image/jpg
response.setContentType(fileType);
// Make sure to show the download dialog
response.setHeader("Content-disposition","attachment; filename=yourcustomfilename.pdf");
// Assume file name is retrieved from database
// For example D:\\file\\test.pdf
File my_file = new File(fileName);
// This should send the file to browser
OutputStream out = response.getOutputStream();
FileInputStream in = new FileInputStream(my_file);
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0){
out.write(buffer, 0, length);
}
in.close();
out.flush();
}
}
That depends. If said file is publicly available via your HTTP server or servlet container you can simply redirect to via response.sendRedirect().
If it's not, you'll need to manually copy it to response output stream:
OutputStream out = response.getOutputStream();
FileInputStream in = new FileInputStream(my_file);
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0){
out.write(buffer, 0, length);
}
in.close();
out.flush();
You'll need to handle the appropriate exceptions, of course.
Try with Resource
File file = new File("Foo.txt");
try (PrintStream ps = new PrintStream(file)) {
ps.println("Bar");
}
response.setContentType("application/octet-stream");
response.setContentLength((int) file.length());
response.setHeader( "Content-Disposition",
String.format("attachment; filename=\"%s\"", file.getName()));
OutputStream out = response.getOutputStream();
try (FileInputStream in = new FileInputStream(file)) {
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
}
out.flush();
The easiest way to implement the download is that you direct users to the file location, browsers will do that for you automatically.
You can easily achieve it through:
HttpServletResponse.sendRedirect()
And to send a largFile
byte[] pdfData = getPDFData();
String fileType = "";
res.setContentType("application/pdf");
httpRes.setContentType("application/.pdf");
httpRes.addHeader("Content-Disposition", "attachment; filename=IDCards.pdf");
httpRes.setStatus(HttpServletResponse.SC_OK);
OutputStream out = res.getOutputStream();
System.out.println(pdfData.length);
out.write(pdfData);
System.out.println("sendDone");
out.flush();