You could create a file and -without storing it on the server- return it immediately as a downloadable file to the client.
This has the advantage that you don't need temporary storage on your server that might grow and keep growing unless you regularly clean it out.
Ofcourse if you wish to create an "archive" of old CSV files as a service to your clients then this is no real advantage. But most of the time the 'create/offer-for-download/throw-away' is the more interesting approach.
Here's some example code that may give you some idea:
1) the servlet (note: exception handling not shown)
public class CsvDownloadServlet extends HttpServlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
// fetch parameters from HTTP request
String param = (String)request.getParameter("p");
if (param == null)
{
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Parameter p missing");
return;
}
.... perhaps fetch more parameters ....
.... build your CSV, using the parameter values ....
String result = .... // suppose result is your generated CSV contents
String filename = .... // choose a file name that your browser will suggest when saving the download
// prepare writing the result to the client as a "downloadable" file
response.setContentType("text/csv");
response.setHeader("Content-disposition", "attachment; filename=\""+filename+"\"");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "-1");
// actually send result bytes
response.getOutputStream().write(result.getBytes());
}
}
2) configuration in WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
....
<servlet>
<display-name>download</display-name>
<servlet-name>download</servlet-name>
<servlet-class>com.mypackage.CsvDownloadServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>download</servlet-name>
<url-pattern>/download</url-pattern>
</servlet-mapping>
....
</web-app>
3) the link on your page to trigger the download:
<a href="/myapp/download?p=myparamvalue">Click Here</a>
Here, /myapp is the "context-root" of your application, /download is configured in web.xml to be the location that triggers the CsvDownloadServlet code. p is an example parameter (see servlet code).
If you have a form where the user fills in the parameter values, it could look like this:
<form method='GET' action='/myapp/download'>
Enter a value for parameter "p":
<input id="p" type="text" size="10" name="p">
<input type="submit" value="Generate and Download">
</form>
This has the same effect as the previous <a> link, only the parameters are user supplied. As soon as the user clicks the submit button, the servlet code will be invoked and the CSV generation and subsequent download will start.
Again, user input checking is not shown.
You could create a file and -without storing it on the server- return it immediately as a downloadable file to the client.
This has the advantage that you don't need temporary storage on your server that might grow and keep growing unless you regularly clean it out.
Ofcourse if you wish to create an "archive" of old CSV files as a service to your clients then this is no real advantage. But most of the time the 'create/offer-for-download/throw-away' is the more interesting approach.
Here's some example code that may give you some idea:
1) the servlet (note: exception handling not shown)
public class CsvDownloadServlet extends HttpServlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
// fetch parameters from HTTP request
String param = (String)request.getParameter("p");
if (param == null)
{
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Parameter p missing");
return;
}
.... perhaps fetch more parameters ....
.... build your CSV, using the parameter values ....
String result = .... // suppose result is your generated CSV contents
String filename = .... // choose a file name that your browser will suggest when saving the download
// prepare writing the result to the client as a "downloadable" file
response.setContentType("text/csv");
response.setHeader("Content-disposition", "attachment; filename=\""+filename+"\"");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "-1");
// actually send result bytes
response.getOutputStream().write(result.getBytes());
}
}
2) configuration in WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
....
<servlet>
<display-name>download</display-name>
<servlet-name>download</servlet-name>
<servlet-class>com.mypackage.CsvDownloadServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>download</servlet-name>
<url-pattern>/download</url-pattern>
</servlet-mapping>
....
</web-app>
3) the link on your page to trigger the download:
<a href="/myapp/download?p=myparamvalue">Click Here</a>
Here, /myapp is the "context-root" of your application, /download is configured in web.xml to be the location that triggers the CsvDownloadServlet code. p is an example parameter (see servlet code).
If you have a form where the user fills in the parameter values, it could look like this:
<form method='GET' action='/myapp/download'>
Enter a value for parameter "p":
<input id="p" type="text" size="10" name="p">
<input type="submit" value="Generate and Download">
</form>
This has the same effect as the previous <a> link, only the parameters are user supplied. As soon as the user clicks the submit button, the servlet code will be invoked and the CSV generation and subsequent download will start.
Again, user input checking is not shown.
Use this code:
<a href="path for the file" download="filename with extension"><u>Download</u></a>
Videos
I am posting here for anybody here who looking for answer on it.
On JSP file, use this for link
<<li><a href="/reportFetch?filePath=<%=file.getAbsolutePath()%>&fileName=<%=file.getName()%>" target="_top"><%=list[i]%></a><br>
and create the servlet
...
import javax.activation.MimetypesFileTypeMap;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/reportFetch")
public class Report extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
String filePath = request.getParameter("filePath");
String fileName = request.getParameter("fileName");
MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();
String mimeType = mimeTypesMap.getContentType(request.getParameter("fileName"));
response.setContentType(mimeType);
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
OutputStream out = response.getOutputStream();
FileInputStream in = new FileInputStream(filePath);
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.flush();
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
For some reason, the above answers failed, but this solution works:
index.jsp
<form action="download" method="GET">
<input type="hidden" name="filePath" value="<%=file.getAbsolutePath()%>" />
<input type="hidden" name="fileName" value="<%=file.getName()%>" />
<input type="submit" value="DOWNLOAD" />
</form>
DownloadServlet.java
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.activation.MimetypesFileTypeMap;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String filePath = req.getParameter("filePath");
String fileName = req.getParameter("fileName");
MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();
String mimeType = "APPLICATION/OCTET-STREAM";
if (null != fileName && !"".equals(fileName)) {
mimeType = mimeTypesMap.getContentType(fileName);
} else {
fileName = "file.unknown";
}
if (filePath != null) {
resp.setContentType(mimeType);
resp.setHeader("Content-disposition", "attachment; filename=" + fileName);
OutputStream out = resp.getOutputStream();
FileInputStream in = new FileInputStream(filePath);
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.flush();
} else {
resp.getOutputStream().println("400 Bad Request, please provide the required parameters: /download?filePath=...&fileName=...");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}