I am using struts2 and jasper report in a little web application. I am getting the following error when I am trying to export the report. Report is exported successfully but an error is printed in the log and struts unable to redirect to the success page after executing the action as well.
I have searched this through the internet but I was unable to clarify this. Could anybody please help me to clarify this.
ERROR Dispatcher - Exception occurred during processing request: Cannot call sendRedirect() after the response has been committed
java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed
at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:482)
at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:137)
at org.springframework.security.web.context.SaveContextOnUpdateOrErrorResponseWrapper.sendRedirect (SaveContextOnUpdateOrErrorResponseWrapper.java:74)
at org.apache.struts2.dispatcher.ServletRedirectResult.sendRedirect(ServletRedirectResult.java:243)
at org.apache.struts2.dispatcher.ServletRedirectResult.doExecute(ServletRedirectResult.java:226)
at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
at org.apache.struts2.dispatcher.ServletRedirectResult.execute(ServletRedirectResult.java:161)
at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:367)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:271)
at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)
at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)
at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265)
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept (AnnotationValidationInterceptor.java:68)
<struts>
<package name="user" namespace="/" extends="struts-default">
<action name="testJPReport" class="testUserSupport" method="exportReportAsPdf">
<result name="success">report.jsp</result>
</action>
</package>
</struts>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="testUserSupport"
class="net.lavanya.app.lav.report.web.TestUserAction">
</bean>
public class TestUserAction extends ExportSupport{
public String exportReportAsPdf() {
Map<String, Object> param = new HashMap<>();
try {
DataBeanMaker dataBeanMaker = new DataBeanMaker();
ArrayList<Test> dataBeanList = dataBeanMaker.getTestDataBeanList();
processReport(ReportTypeEnum.PDF, dataBeanList, "test", param);
} catch (Exception exception) {
exception.printStackTrace();
}
return SUCCESS;
}
}
package net.test.app.report.web;
import com.opensymphony.xwork2.ActionSupport;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
public class ExportSupport extends ActionSupport implements ServletResponseAware, ServletRequestAware {
private HttpServletResponse httpServletResponse;
private HttpServletRequest httpServletRequest;
private String contentType = "APPLICATION/OCTET-STREAM";
@Override
public void setServletResponse(HttpServletResponse httpServletResponse) {
this.httpServletResponse = httpServletResponse;
}
@Override
public void setServletRequest(HttpServletRequest httpServletRequest) {
this.httpServletRequest = httpServletRequest;
}
public void processReport(ReportTypeEnum reportTypeEnum, List<?> beansList, String reportName, Map<String, Object> parameters) throws Exception {
switch (reportTypeEnum) {
case PDF:
processReportAsPDF(beansList, reportName, parameters);
break;
default:
throw new RuntimeException("Un supported report type");
}
}
private void processReportAsPDF(List<?> beansList, String reportName, Map<String, Object> parameters) throws Exception {
System.out.println(">>>>>>>Start processing of pdf report!");
JRBeanCollectionDataSource beanColDataSource = new JRBeanCollectionDataSource(beansList);
JasperDesign jasperDesign = JRXmlLoader.load(getJasperFilePath(reportName));
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, beanColDataSource);
setResponseHeaderData(reportName, ReportTypeEnum.PDF);
ServletOutputStream sos = httpServletResponse.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint, sos);
sos.flush();
sos.close();
httpServletResponse.getOutputStream().flush();
httpServletResponse.getOutputStream().close();
System.out.println(">>>>>>>End processing of pdf report!");
return;
}
private InputStream getJasperFilePath(String reportName) throws FileNotFoundException {
System.out.println(">>>>>>> Path : " + httpServletRequest.getSession().getServletContext().getRealPath("/reports/" + reportName + ".jrxml"));
return new FileInputStream(httpServletRequest.getSession().getServletContext().getRealPath("/reports/" + reportName + ".jrxml"));
}
private void setResponseHeaderData(String reportName, ReportTypeEnum reportTypeEnum) {
httpServletResponse.setContentType(contentType);
StringBuilder headerBuilder = new StringBuilder();
headerBuilder.append("Attachment;Filename=").append("\"").append(reportName).append(".").
append(reportTypeEnum.getReportType()).append("\"");
httpServletResponse.setHeader("Content-Disposition", headerBuilder.toString());
System.out.println(">>>>>>>End of setting response headers for report download");
}
}