Spring MVC Contrôleur de code: getOutputStream() a déjà été appelée pour cette réponse

Je suis en train d'assembler un fichier CSV à partir de quelques DB de données et l'envoi au client de mon contrôleur Spring MVC (et services associés). Je suis en utilisant SuperCSV pour gérer la rédaction et à la sortie: http://supercsv.sourceforge.net/

Alors, voici la méthode de contrôleur:

@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();
    }
};

C'est en fait aller de l'avant et obtenir la réponse au navigateur client qui déclenche le téléchargement du fichier csv.

Deux problèmes:

1) je me fais un tas de serveur-côté exception spewage (ci-dessous)

2) Le fichier CSV contient uniquement les en-têtes et pas de données, en dépit de la allRecords liste de montrer entièrement rempli dans le débogueur.

J'espère que la défaillance à remplir est causée par l'exception, mais je me méfie. Exception trace:

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)

L'exception semble se passer comme je suis de le voir 4 fois par invocation de cette méthode.

Toute la documentation que j'ai trouvé a des gens qui l'incorporation de leur réponse.getOutputStream() à l'intérieur de scriptlets au lieu d'être dans un servlet. La méthode que j'ai obtenu ci-dessus est à l'intérieur du contrôleur Spring MVC, de sorte que le conseiller de "déplacer vers une servlet!" ne semble pas s'appliquer ici. À partir de ce que je peux dire, je suis seulement en invoquant la réponse.getOutputStream() une seule fois, et la méthode est de sauter sur le premier appel.

Je suis perplexe. De l'aide?

  • Essayez de ne pas fermer le flux de sortie. stackoverflow.com/questions/1829784/...
  • Un bon morceau de l'info, là, mais pas la source de mon problème malheureusement. Je l'ai enlevé pour éviter à l'avenir toute les questions mais il ne semble pas être la cause de mon IllegalStateException.
InformationsquelleAutor Raevik | 2012-09-07