Search code examples
javaopencsv

Wrong output to csv file being written to OutputStream


So I have a form in my jsp file and when I click the button I want it do do a sql query and turn the result to s csv file and then download. I am doing this through a servlet, the problem I am encountering is that in the csv file being downloaded I am getting "com.opencsv.CSVWriter@771aa22" instead of my query

Here is the doGet in question

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String sql QueryConstant.CFOUSERQUERY;
    Connection conn =null;
    Statement stmt = null;
    ResultSet rs = null;
    String csvResult="";
    try{
        ConnectionManager connMan= GFOServer.GetGoldInt.ConnectionManager();
        conn connMan.allocateConnection(); 
        stmt. conn.createStatement();
        rs=stmt.executeQuery(sql);
        CSVWriter writer new CSVWriter(new FileWriter("CFOUserQueryReport.csv"));
        writer.writeall (rs, true);
        csvResult= writer.toString();
        writer.close();
        connMan.closeStatement(stmt);
        connMan.closeResultSet(rs);
        connMan.deallocateConnection(conn);

        response.setContentType("text/csv");
        response.setHeader("Content-disposition", "attachment; filename=CFOUserQueryReport.csv");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Expires", "-1");
        response.getOutputStream().write(csvResult.getBytes());
    } catch (Exception e) {
        e.getMessage();
    }
}

Solution

  • This line is incorrect:

        csvResult = writer.toString();
    

    The toString() method on a Writer is the toString method inherited from java.lang.Object. That produces the string that you saw.

    writer is a FileWriter and there is no method on a FileWriter that will give you the stuff that you wrote to the file; i.e. in the writeAll call.

    If you need the CSV that you wrote to the file as a string, you could:

    • write it to a StringWriter instead, or
    • use Files.readString(Path).

    Alternatively you could avoid creating an in-memory string by copying the file to the socket as a byte stream. For example, using transferTo as per Transerring files between FileChannel and Socket.

    The other thing to note is that your code has a bunch of assumptions about the platform default character set. This could be problematic if the characters in the text in the CSV aren't all plain ASCII.