Spring MVC Controller代码:已经为此响应调用了getOutputStream()

Rae*_*vik 1 java csv spring exception spring-mvc

我正在尝试从一些数据库数据中组装一个CSV文件,并从我的Spring MVC控制器(和相关服务)发送到客户端.我正在使用SuperCSV来处理写作和输出:http://supercsv.sourceforge.net/

所以,这是控制器方法:

@RequestMapping(value="/getFullReqData.html", method = RequestMethod.GET)
public void getFullData(HttpSession session, HttpServletRequest request, HttpServletResponse response) throws IOException{
    logger.info("INFO:  ******************************Received request for full Req data dump");

    List<Requirement> allRecords = reqService.getFullDataSet(ProjectService.getProjectID((String)session.getAttribute("currentProject")));
    response.setContentType("text/csv;charset=utf-8"); 
    response.setHeader("Content-Disposition","attachment; filename=nistData.csv");
    OutputStream fout= response.getOutputStream();  
    OutputStream bos = new BufferedOutputStream(fout);   
    OutputStreamWriter outputwriter = new OutputStreamWriter(bos); 

    ICsvBeanWriter writer = new CsvBeanWriter(outputwriter, CsvPreference.EXCEL_PREFERENCE);
    try {
      final String[] header = new String[] { 
              "ReqID", 
              "ColName1",
              "ColName2",
              "ColName3",
              "ColName4",
              "ColName5", 
              "ColName6",
              "ColName7",
              "ColName8",                                 
              "ColName9",
              "ColName10" };

      // the actual writing
      writer.writeHeader(header);

      for(Requirement aCR : allRecords){
          writer.write(aCR, header);
      }

    } finally {
        writer.close();
    }
};
Run Code Online (Sandbox Code Playgroud)

这实际上是向前移动并获得客户端浏览器的响应,触发csv文件的下载.

两个问题:

1)我得到了一堆服务器端异常消息(下面)

2)尽管allRecords列表在调试器中显示为完全填充,但CSV文件中只包含标题而没有数据.

我希望失败的人是由异常造成的,但我很怀疑.异常跟踪:

SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:633)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:214)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:105)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:105)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:182)
at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:123)
at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:80)
at org.apache.jsp.error_jsp._jspService(error_jsp.java:102)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
Run Code Online (Sandbox Code Playgroud)

该异常看起来传递,因为我每次调用此方法时都会看到它4次.

我发现的所有文档都有人将他们的response.getOutputStream()嵌入到scriptlet中,而不是在servlet中.我上面提到的方法是在Spring MVC控制器中,所以建议"将它移动到servlet!" 似乎不适用于此.据我所知,我只调用了一次response.getOutputStream(),并且该方法在第一次调用时爆炸.

我很难过.救命?

Bij*_*men 7

您的流可能在请求映射方法中的某处引发异常 - 可能在writer.write(aCR, header);其中转到finally块,关闭响应流,然后异常冒泡到servlet,它尝试通过错误页面处理它(检查您的web.xml error-page标签),因为响应流已关闭,无法干净地呈现错误jsp,因此您看到的是异常消息.

如果您能够在控制器中捕获异常并打印堆栈跟踪以查看在写入输出流时控制器中可能出现的问题,那将是一件好事.