I found another way to pass the connection as a parameter and then close it.
PROBLEM:
I am implementing a solution to the above problem, since every time I call the PDF file, a new connection was created, so when the application reaches the maximum limit of open connections, it crashes.
ReportesDAOJDBC reportes; public void setReportes(ReportesDAOJDBC reportes) { this.reportes = reportes; } public ModelAndView leoTest(HttpServletRequest request, HttpServletResponse response) throws Exception { Map < String, Object > model = new HashMap < String, Object >(); model.put("PARAMCONTRARECIBO", new Integer(1101)); model.put("PARAMDOCTOS", new Integer(1101)); model.put("REPORT_CONNECTION", reportes.getConexion()); return new ModelAndView("leoTest",model); }
The parameter for transferring a connection to JasperReport is REPORT_CONNECTION, but, as I said, by doing this, you will get many trolleybuses.
MY DECISION:
ReportesDAOJDBC reportes; public void setReportes(ReportesDAOJDBC reportes) { this.reportes = reportes; } public ModelAndView leoTest(HttpServletRequest request, HttpServletResponse response) throws Exception { Map < String, Object > model = new HashMap < String, Object >(); model.put("PARAMCONTRARECIBO", new Integer(1101)); model.put("PARAMDOCTOS", new Integer(1101)); model.put("OBJETO_CONEXION", reportes); return new ModelAndView(new PdfView("leoTest"),model); }
As you can see, I implement my own PdfView and I pass the constructor the name of the define key in the view.properties file, and also pass the link to my DAOs (reports) as a HashMap parameter, the parameter name is "OBJETO_CONEXION". Here is the code for ReportesDAOJDBC:
public class ReportesDAOJDBC extends JdbcDaoSupport { public Connection getConexion() { Connection con ; try { con = getDataSource().getConnection(); } catch (Exception e) { e.printStackTrace(); return null; } return con; } public void closeConecction(Connection con) { try { if (con != null) { con.close(); } } catch (Exception e) { e.printStackTrace(); } } }
Then the next step is to show you the code for my own implementation of PdfView.
import java.io.File; import java.io.OutputStream; import java.sql.Connection; import java.util.Map; import java.util.ResourceBundle; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import mx.com.mexican.leinksy.dao.jdbc.ReportesDAOJDBC; import mx.com.mexican.leinksy.utils.Utils; import net.sf.jasperreports.engine.JasperExportManager; import net.sf.jasperreports.engine.JasperFillManager; import net.sf.jasperreports.engine.JasperPrint; import net.sf.jasperreports.engine.JasperReport; import net.sf.jasperreports.engine.util.JRLoader; import org.springframework.web.servlet.View; import org.springframework.web.servlet.view.ResourceBundleViewResolver; public class PdfView implements View { private static final String CONTENT_TYPE = "application/pdf"; private String JASPER_URL; public PdfView(String jasperUrl){ this.JASPER_URL = jasperUrl+".url"; } @Override public String getContentType() { return CONTENT_TYPE; } @Override public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println(Utils.getRealPath(request)); ResourceBundle rb = ResourceBundle.getBundle("view"); ReportesDAOJDBC reporte = (ReportesDAOJDBC)model.get("OBJETO_CONEXION"); Connection con = reporte.getConexion(); String jasperFilePath = Utils.getRealPath(request) + rb.getString( JASPER_URL ); JasperReport jasperReport = (JasperReport)JRLoader.loadObject(new File(jasperFilePath)); JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, model, con); try{ OutputStream out = response.getOutputStream(); JasperExportManager.exportReportToPdfStream(jasperPrint, out); out.flush(); out.close(); }catch(Exception e){ e.printStackTrace(); } reporte.closeConecction(con); } }
As you can see, I read the view.properties file using the ResourceBoundle class to get the path and name of the .jasper file to load. Also note that I am not compiling a .jrxml file. I just upload the compiled file, I compile jrxml using IREPORTS. I also have a utility to get the path to my .jasper file, here is the code if you have no idea how to do this.
public static String getRealPath(HttpServletRequest req) { ServletContext context = req.getSession().getServletContext(); String path = context.getRealPath("/"); if (path != null) { if (!path.endsWith(File.separator)) { path += File.separator; } } return path; }
With this implementation, I can control where to open a closed connection, I also respect the MVC SPRING model, and I still use view.properties.
And at the moment, maybe you are asking WHAT CAN DO IF I WANT THE EXCEL FILE, well, I also implement XlsView (Ajuuaaaa !!!). Here is the code:
import java.io.File; import java.io.OutputStream; import java.sql.Connection; import java.util.Map; import java.util.ResourceBundle; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import mx.com.mexican.leinsky.dao.jdbc.ReportesDAOJDBC; import mx.com.mexican.leinksy.utils.Utils; import net.sf.jasperreports.engine.JasperExportManager; import net.sf.jasperreports.engine.JasperFillManager; import net.sf.jasperreports.engine.JasperPrint; import net.sf.jasperreports.engine.JasperReport; import net.sf.jasperreports.engine.export.JRXlsExporter; import net.sf.jasperreports.engine.export.JRXlsExporterParameter; import net.sf.jasperreports.engine.util.JRLoader; import org.springframework.web.servlet.View; import org.springframework.web.servlet.view.ResourceBundleViewResolver; public class XlsView implements View { private static final String CONTENT_TYPE = "application/vnd.ms-excel"; private String JASPER_URL; private String FILE_NAME = "XLSFile"; public XlsView(String jasperUrl){ this.JASPER_URL = jasperUrl+".url"; } @Override public String getContentType() { return CONTENT_TYPE; } @Override public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { if(model.get("FILE_NAME")!=null){ this.FILE_NAME = model.get("FILE_NAME").toString(); } ResourceBundle rb = ResourceBundle.getBundle("view"); ReportesDAOJDBC reporte = (ReportesDAOJDBC)model.get("OBJETO_CONEXION"); Connection con = reporte.getConexion(); String jasperFilePath = Utils.getRealPath(request) + rb.getString( JASPER_URL ); JasperReport jasperReport = (JasperReport)JRLoader.loadObject(new File(jasperFilePath)); JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, model, con); response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-Disposition","attachment; filename=\""+FILE_NAME+".xls\""); response.setHeader("Pragma", "No-cache"); response.setDateHeader("Expires", 1); try{ OutputStream out = response.getOutputStream(); JRXlsExporter exporterXLS = new JRXlsExporter(); exporterXLS.setParameter(JRXlsExporterParameter.JASPER_PRINT,jasperPrint); exporterXLS.setParameter(JRXlsExporterParameter.OUTPUT_STREAM,out); exporterXLS.exportReport(); out.flush(); out.close(); }catch(Exception e){ e.printStackTrace(); } reporte.closeConecction(con); }
}
So this is my solution, hope this helps !!!