How to download csv file without writing it using OpenCsv - java

I am using OpenCsv API and now i am stuck in some problem.Here's my code
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
List<UserRegData> userRegDataList = new ArrayList<UserRegData>();
HttpSession session = request.getSession();
userRegDataList = (List<UserRegData>) session.getAttribute("referralData");
List<String[]> dataToWrite = new ArrayList<String[]>();
String csv = "E:\\carewave_backup\\csv\\UserReferral.csv";
CSVWriter writer = new CSVWriter(new FileWriter(csv));
for (UserRegData obj : userRegDataList) {
dataToWrite.add(new String[]{obj.getReferred_by_name(), obj.getInvitee_name(), obj.getInvitee_email(), obj.getInvitee_date(), obj.getIsInviteeRegistered(), obj.getDate_of_invitee_registered()});
}
writer.writeAll(dataToWrite);
writer.close();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
out.close();
}
}
This servlet basically retrieves list from session and writes it to csv file.This servlet is triggered after user clicks download csv button.Now what i need is, browser should give a download dialogue.Is there anyway to download it in csv format without writing it to file first?.

I assume you're asking about how to stream the output on the server directly to the client without writing it first to a temp file on the server.
You don't need to write the data to a file first.
Set the resonse content-type to text/csv
Call getOutputStream() on the response object
Write the contents of dataToWrite as individual lines to the output stream
No disk file needed.

Related

FileNotFoundException with JSP but Java code works

I am trying to use jsp and java to display information read from a csv to a website. I'm using Tomcat v9.0 with Eclipse.
The java code works as expected when running it just in java—it reads the csv data into an ArrayList of Song objects. However, when running the jsp file, it throws a filenotfoundexception.
The original java code reads and parses the csv in the getter function of "ReadBillboardCSV" here:
public ArrayList<BillboardSong> getReadBillboardCSV() throws FileNotFoundException {
Reader in = new FileReader("testFile.csv");
ArrayList<BillboardSong> readSongs = new ArrayList<BillboardSong>();
try {
Iterable<CSVRecord> records = CSVFormat.RFC4180.parse(in);
for (CSVRecord record : records) {
BillboardSong newSong = new BillboardSong();
readSongs.add(newSong);
newSong.setPosition(Integer.parseInt(record.get(0)));
My servlet calls the getter, then sets the attribute.
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession ses = request.getSession(true);
ReadBillboardCSV readData = new ReadBillboardCSV();
ArrayList<BillboardSong> songsArray = readData.getReadBillboardCSV();
ses.setAttribute("billboardArray", songsArray);
}
Here is the main portion of the jsp:
<%
RequestDispatcher rd = request.getRequestDispatcher("/ServletOne");
rd.forward(request, response);
%>
Is there a reason it cannot read the file when I run it on Tomcat?

How to write to a txt file in Servlet and automatically download it when requests

I want to create a txt file in my Servlet and automatically download it at the client side when client requests. I have below code to write to a txt, but it gives access denied error in Netbeans IDE using glassfishserver. How can I do it?
//File creation
String strPath = "C:\\example.txt";
File strFile = new File(strPath);
boolean fileCreated = strFile.createNewFile();
//File appending
Writer objWriter = new BufferedWriter(new FileWriter(strFile));
objWriter.write("This is a test");
objWriter.flush();
objWriter.close();
Its not a thing you do it in JSP. You better have a Servlet and just create a Outputstream and put your text in it. Then flush that stream into the HttpServletResponse.
#WebServlet(urlPatterns = "/txt")
public class TextServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
response.setContentType("text/plain");
response.setHeader("Content-Disposition", "attachment; filename=\"example.txt\"");
try {
OutputStream outputStream = response.getOutputStream();
String outputResult = "This is Test";
outputStream.write(outputResult.getBytes());
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Remember you need to set the content-type text/plain and a Content-Disposition header that mentions filename and tells broswer that it should be downloaded as file attachment.
This is what Content-Disposition header is about in concise description
In a regular HTTP response, the Content-Disposition response header is
a header indicating if the content is expected to be displayed inline
in the browser, that is, as a Web page or as part of a Web page, or as
an attachment, that is downloaded and saved locally.
If you are a beginner. You may like to learn more about from this
What is HTTP, Structure of HTTP Request and Response?
How a Servlet Application works
Difference Between Servlet and JSP

GWT Download Excel .xlsx gives me a corrupted file

I'm working on a GWT application which gives every team in the company an overview about what they have to do.
The program is working, but now we want that the Excel table which you can download will be a .xlsx and not a .xls.
This whole project is new for me and I consider myself as a beginner in GWT.
In the code, when the filename is given for the Excel table, there is a +".xls" at the end. When I change it to +".xlsx" and test the application, the download still works. However, when I try to open the file in Excel, it shows me an error message and tells me the file is corrupted. (.xls works)
Can you explain to me how a download works in GWT with a serverSite generated Excel?
Maybe you have some ideas what causes the file to be corrupted
(sadly the programmer of this application is on holiday, so I cannot ask him)
public class Download extends HttpServlet {
private static final long serialVersionUID = 5580666921970339383L;
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String filename = (String)request.getSession().getAttribute(CrossReportConstants.ATTR_FILENAME);
byte[] data = (byte[])request.getSession().getAttribute(CrossReportConstants.ATTR_REPORT);
request.getSession().setAttribute(CrossReportConstants.ATTR_FILENAME, null);
request.getSession().setAttribute(CrossReportConstants.ATTR_REPORT, null);
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=" + filename);
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setContentLength(data.length);
try {
InputStream in = new ByteArrayInputStream(data);
ServletOutputStream out = response.getOutputStream();
byte[] outputByte = new byte[4096];
// copy binary contect to output stream
while (in.read(outputByte, 0, 4096) != -1) {
out.write(outputByte, 0, 4096);
}
in.close();
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Now as you provided code you question can be easily answered:
The shown code defines a HttpServlet. Somewhere in your project there is a file called web.xml. In this file the class you showed is mapped to an url pattern, therefore you server knows that a specific url should be handled by this servlet.
The servlet you showed first extracts the file name and the file content out of the session. Additional the http response is prepared and the file content is written out. Now you just have to replace the content type of the response with the one for xlsx.
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
The browser which handles the http response now recognizes the download as a .xlsx file. The file extension does not really matter in this step, as you noticed.
When the original programmer of the servlet comes back from his hollidays, you should/could recommend him to use response.sendError() (with an appropriate http status code) instead of e.printStackTrace(). Then the user of the servlet can better understand if something do not work and who is to blame.

write the file and download the file same as of attachments

i have a requirement where i get byte array (byte[]) data from database, i need to save this data in a file and allow the user to save where ever he want to save, same as downloading the attachments.The file name and extension also i'm retrieving from database. I'm using java,spring-mvc for this.
Below is the code:
spring controller:
#RequestMapping(value="/getFile", method = RequestMethod.GET)
public ModelAndView getFile(HttpServletRequest request, HttpServletResponse response) {
ModelAndView mav = new ModelAndView();
//logic to get the data from database
byte[] documentData = document.getDOCUMENTData();
String documentName = document.getDOCUMENTTITLE();
String documentExt = document.getDocumentExtension();
}
Please suggest, i know that using java.io.*, i can write the byte[] data in file and give file name and extension by taking the values declared above, but how can i allow users when clicked on "download file" icon to write the data and save that file where ever he wants same as downloading the attachment.Please suggest. Once user clicks on download file icon control comes to above controller.Thanks.
--EDIT--
Modified code:
#RequestMapping(value="/getFile", method = RequestMethod.GET)
public ModelAndView getFile(HttpServletRequest request, HttpServletResponse response) {
ModelAndView mav = new ModelAndView();
//logic to get the data from database
byte[] documentData = document.getDOCUMENTData();
String documentName = document.getDOCUMENTTITLE();
String documentExt = document.getDocumentExtension();
response.setHeader("Content-Disposition", "attachment;filename="+userDoc.getDOCUMENT_TITLE());
long l = userDoc.getDOCUMENT_SIZE();
int size = (int)l;
response.setContentLength(size);
response.getWriter().write("hello");//i need to write byte[] but for test i kept string.
}
I want user to see save window so that he can save where ever he want same as downloading the attachments from mail.Thanks.
This is a code I'm usign for the same request
HTML page:
<h:commandButton value="Click Here to Download" action="#{reportBean.download}" />
BEAN:
public void download(){
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.setHeader("Content-Disposition", "attachment;filename="+file.getName());
response.setContentLength((int) file.length());
ServletOutputStream out = null;
try {
FileInputStream input = new FileInputStream(file);
byte[] buffer = new byte[1024];
out = response.getOutputStream();
int i = 0;
while ((i = input.read(buffer)) != -1) {
out.write(buffer);
out.flush();
}
FacesContext.getCurrentInstance().getResponseComplete();
input.close();
} catch (IOException err) {
err.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException err) {
err.printStackTrace();
}
}
}
Just make sure you have a File object named file
You have two options to achieve this:
One is to write the file in your server's local filesystem in an internet accesible folder. You can configure which of your server's local folders are accesible from internet in your Apache/IIS serttings. Then you update your HTML so your "download file" link points to that file through an URL.
The other option is, like #an3sarmiento did, to return the file as a byte[] stream to the browser. For this option to work, you have to send, along with the file content, a response header in which you tell the browser you are returning a downloadable file as a stream. You do that with the line:
response.setHeader("Content-Disposition", "attachment;filename="+[your file name]);
response.setContentLength([your file's length or bytes count]);
response.getWriter.write([your file's content as byte array]);
In the line above I assume you are working with Java Servlets and you have an HttpServletResponse variable named reponse, which you will respond to the browser's HTTP POST or GET request.

Fetching JSON object from Servlet Java

I want to create an application that will fetch a JSON object from a servlet to deserialize it, and then use its variables to do other things.
My servlet has the following code in the doPost:
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ObjectOutputStream os;
os = new ObjectOutputStream(response.getOutputStream());
String s = new String("A String");
Gson gson = new Gson();
String gsonObject= gson.toJson(s);
os.writeObject(gsonObject);
os.close();
}
Now, while the servlet is running, I can access it via a browser, if I post same code in the doGet method, that would download a servlet file, which is not what I want.
What should I use in my second application that would connect to the servlet, fetch the object, so that I can manipulate it later?
Thanks in advance.
You need few changes in your servlet :
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String s = new String("A String");
String json = new Gson().toJson(s);
this.response.setContentType("application/json");
this.response.setCharacterEncoding("UTF-8");
Writer writer = null;
try {
writer = this.response.getWriter();
writer.write(json);
} finally {
try {
writer.close();
}
catch (IOException ex) {
}
}
}
If its downloading the servlet file instead of showing it in the browser , most probably you have not set the content type in the response. If you are writing a JSON string as the servlet response , you have to use
response.setContentType("text/html");
response.getWriter().write(json);
Please note the order , its "text/html" and not "html/text"
IfI understood the question correctly then you can use, java.net.HttpURLConnection and java.net.URL objects to create a connection to this servlet and read the JSON streamed by the above JSON servlet in your second servlet.

Categories