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.
Vous devez vous connecter pour publier un commentaire.
Votre flux est probablement lever une exception, quelque part dans la demande, la méthode mappée - probablement dans
writer.write(aCR, header);
qui va ensuite le bloc finally, ferme le flux de réponse, alors l'exception des bulles jusqu'à la servlet, qui essaye de le manipuler par une page d'erreur(vérifiez votre web.xmlerror-page
tags) , qui, en raison du flux de la réponse est fermé ne peut pas rendre l'erreur jsp proprement et donc le message d'exception vous de voir.Il sera bon si vous pouvez intercepter l'exception dans le contrôleur et imprimer la trace de la pile pour voir ce qui pourrait mal se passer dans le contrôleur lors de l'écriture dans le flux de sortie.
Pouvez-vous faire le travail avec printWriter à la place: