I'm trying to get reports from web page. Actually report is generated as expected and it can be downloaded properly. But I get IllegalStateException in console, while debugging. Stack trace refers one of my method called "AddResponseHeaderFilter.doFilter()". The method only sets charset UTF-8 and the class implements javax.servlet.Filter.
Technology I used: Bussiness logic: Java(Spring), Report Engine: JasperReports, Application Server: Tomcat9
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
Stack Trace
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:582) ~[catalina.jar:9.0.20]
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:227) ~[catalina.jar:9.0.20]
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:114) ~[servlet-api.jar:4.0.FR]
at org.springframework.boot.web.servlet.support.ErrorPageFilter$ErrorWrapperResponse.getWriter(ErrorPageFilter.java:374) ~[spring-boot-2.2.0.M2.jar:2.2.0.M2]
at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:360) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:189) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1370) ~[spring-webmvc-5.2.0.M1.jar:5.2.0.M1]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1116) ~[spring-webmvc-5.2.0.M1.jar:5.2.0.M1]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1055) ~[spring-webmvc-5.2.0.M1.jar:5.2.0.M1]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.2.0.M1.jar:5.2.0.M1]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.2.0.M1.jar:5.2.0.M1]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) ~[spring-webmvc-5.2.0.M1.jar:5.2.0.M1]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[servlet-api.jar:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.2.0.M1.jar:5.2.0.M1]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[servlet-api.jar:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[catalina.jar:9.0.20]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[catalina.jar:9.0.20]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-websocket.jar:9.0.20]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[catalina.jar:9.0.20]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[catalina.jar:9.0.20]
at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:109) ~[catalina.jar:9.0.20]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[catalina.jar:9.0.20]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[catalina.jar:9.0.20]
at com.beybo.filters.AddResponseHeaderFilter.doFilter(AddResponseHeaderFilter.java:33) ~[classes/:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[catalina.jar:9.0.20]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[catalina.jar:9.0.20]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:130) ~[spring-boot-2.2.0.M2.jar:2.2.0.M2]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:66) ~[spring-boot-2.2.0.M2.jar:2.2.0.M2]
at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:105) ~[spring-boot-2.2.0.M2.jar:2.2.0.M2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.2.0.M1.jar:5.2.0.M1]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:123) ~[spring-boot-2.2.0.M2.jar:2.2.0.M2]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[catalina.jar:9.0.20]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[catalina.jar:9.0.20]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.2.0.M1.jar:5.2.0.M1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.2.0.M1.jar:5.2.0.M1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[catalina.jar:9.0.20]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[catalina.jar:9.0.20]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200) ~[catalina.jar:9.0.20]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[catalina.jar:9.0.20]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) ~[catalina.jar:9.0.20]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[catalina.jar:9.0.20]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[catalina.jar:9.0.20]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678) ~[catalina.jar:9.0.20]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[catalina.jar:9.0.20]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[catalina.jar:9.0.20]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) ~[tomcat-coyote.jar:9.0.20]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) ~[tomcat-coyote.jar:9.0.20]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:836) ~[tomcat-coyote.jar:9.0.20]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1839) ~[tomcat-coyote.jar:9.0.20]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-coyote.jar:9.0.20]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-util.jar:9.0.20]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
Code
@Controller
@RequestMapping("/report")
public class RaporController {
@GetMapping() String reporting(Model model, HttpServletResponse response) throws IOException {
JasperPrint jasperPrint = reportService.report(new Date(), sqlTable, false);
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", String.format("attachment; filename=\"" + reportService.getFilename() + "\""));
OutputStream out = response.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint, out);
return "home";
}
}
You are mixing the download of the PDF and the rendering of Thymeleaf.
Instead you should return a ResponseEntity with a byte[] that contains the PDF:
@Controller
@RequestMapping("/report")
public class RaporController {
@GetMapping()
public ResponseEntity reporting(Model model, HttpServletResponse response) throws IOException {
JasperPrint jasperPrint = reportService.report(new Date(), sqlTable, false);
ByteArrayOutputStream out = new ByteArrayOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint, out);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_PDF);
headers.setContentDispositionFormData(reportService.getFilename(), reportService.getFilename());
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
return new ResponseEntity(out.toByteArray(), headers, HttpStatus.OK);
}
}