I trying to load jasper report (.jrxml) that i created, i named the report "JREmp1.xml". but i got this error
"HTTP Status 500 - Request processing failed; nested exception is net.sf.jasperreports.engine.JRException: java.io.FileNotFoundException: D:\printpdf.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\JasperExample\jasper\JREmp1.jrxml (The system cannot find the path specified)"
how to got the exact location? here is my JREmp1.xml file location :
and here is code in my controller class :
@RequestMapping(value = "/generateReport", method = RequestMethod.POST)
public String generateReport(
@Valid @ModelAttribute("jasperInputForm") JasperInputForm jasperInputForm,
BindingResult result, Model model, HttpServletRequest request,
HttpServletResponse response) throws JRException, IOException,
NamingException {
if (result.hasErrors()) {
System.out.println("validation error occured in jasper input form");
return "loadJasper";
}
String reportFileName = "JREmp1";
JasperReportDAO jrdao = new JasperReportDAO();
Connection conn = null;
try {
conn = jrdao.getConnection();
String rptFormat = jasperInputForm.getRptFmt();
String noy = jasperInputForm.getNoofYears();
System.out.println("rpt format " + rptFormat);
System.out.println("no of years " + noy);
HashMap<String, Object> hmParams = new HashMap<String, Object>();
hmParams.put("noy", new Integer(noy));
hmParams.put("Title", "Employees working more than " + noy
+ " Years");
JasperReport jasperReport = jrdao.getCompiledFile(reportFileName,
request);
if (rptFormat.equalsIgnoreCase("html")) {
JasperPrint jasperPrint = JasperFillManager.fillReport(
jasperReport, hmParams, conn);
jrdao.generateReportHtml(jasperPrint, request, response); // For
// HTML
// report
}
else if (rptFormat.equalsIgnoreCase("pdf")) {
jrdao.generateReportPDF(response, hmParams, jasperReport, conn); // For
// PDF
// report
}
} catch (SQLException sqlExp) {
System.out.println("Exception::" + sqlExp.toString());
} finally {
if (conn != null) {
try {
conn.close();
conn = null;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
Here is the code in my JasperReportDAO
class :
public JasperReport getCompiledFile(String fileName, HttpServletRequest request) throws JRException {
System.out.println("path " + request.getSession().getServletContext().getRealPath("/jasper/" + fileName + ".jasper"));
File reportFile = new File( request.getSession().getServletContext().getRealPath("/jasper/" + fileName + ".jasper"));
// If compiled file is not found, then compile XML template
if (!reportFile.exists()) {
JasperCompileManager.compileReportToFile(request.getSession().getServletContext().getRealPath("/jasper/" + fileName + ".jrxml"),request.getSession().getServletContext().getRealPath("/jasper/" + fileName + ".jasper"));
}
JasperReport jasperReport = (JasperReport) JRLoader.loadObjectFromFile(reportFile.getPath());
return jasperReport;
}
public void generateReportHtml( JasperPrint jasperPrint, HttpServletRequest req, HttpServletResponse resp) throws IOException, JRException {
HtmlExporter exporter=new HtmlExporter();
List<JasperPrint> jasperPrintList = new ArrayList<JasperPrint>();
jasperPrintList.add(jasperPrint);
exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList));
exporter.setExporterOutput( new SimpleHtmlExporterOutput(resp.getWriter()));
SimpleHtmlReportConfiguration configuration =new SimpleHtmlReportConfiguration();
exporter.setConfiguration(configuration);
exporter.exportReport();
}
public void generateReportPDF (HttpServletResponse resp, Map parameters, JasperReport jasperReport, Connection conn)throws JRException, NamingException, SQLException, IOException {
byte[] bytes = null;
bytes = JasperRunManager.runReportToPdf(jasperReport,parameters,conn);
resp.reset();
resp.resetBuffer();
resp.setContentType("application/pdf");
resp.setContentLength(bytes.length);
ServletOutputStream ouputStream = resp.getOutputStream();
ouputStream.write(bytes, 0, bytes.length);
ouputStream.flush();
ouputStream.close();
}
and here is my JasperInputForm
class :
public class JasperInputForm {
@NotEmpty
private String noofYears;
private String rptFmt="Html";
public String getRptFmt() {
return rptFmt;
}
public void setRptFmt(String rptFmt) {
this.rptFmt = rptFmt;
}
public String getNoofYears() {
return noofYears;
}
public void setNoofYears(String noofYears) {
this.noofYears = noofYears;
}
}
how to get my JREmp1.jrxml
file location properly? I develop this report for Spring MVC application
UPDATE : Here is my complete function code after i update with @Wilson answer (i go with second option that @Wilson said) : this function is inside JasperReportDAO :
public JasperReport getCompiledFile(String fileName, HttpServletRequest request) throws JRException, MalformedURLException, URISyntaxException {
System.out.println("path " + request.getSession().getServletContext().getRealPath("/jasper/" + fileName + ".jasper"));
//File reportFile = new File( request.getSession().getServletContext().getRealPath("/jasper/" + fileName + ".jasper"));
URL resourceUrl = request.getSession().getServletContext().getResource("/WEB-INF/jasper/" + fileName + ".jrxml");
File reportFile = new File(resourceUrl.toURI());
// If compiled file is not found, then compile XML template
if (!reportFile.exists()) {
JasperCompileManager.compileReportToFile(request.getSession().getServletContext().getRealPath("/jasper/" + fileName + ".jrxml"),request.getSession().getServletContext().getRealPath("/jasper/" + fileName + ".jasper"));
}
JasperReport jasperReport = (JasperReport) JRLoader.loadObjectFromFile(reportFile.getPath());
return jasperReport;
}
and i got this error
"HTTP Status 500 - Request processing failed; nested exception is java.lang.IllegalArgumentException: URI scheme is not "file""
How to solve this?
There is a number of way to do to read file with ServeltContext
:
1.
Use ServletContext#getRealPath
String fullPath = request.getSession().getServletContext().getRealPath("/WEB-INF/jasper/" + fileName + ".jrxml");
This will get you the full system path to the resource you are looking for. However, it will not work if the container do not expand the WAR file.
2.
Use ServletContext#getResource
URL resourceUrl = request.getSession().getServletContext().getResource("/WEB-INF/jasper/" + fileName + ".jrxml");
File file = new File(resourceUrl.toURI());
This will return the URL no matter what container you use and where the application is installed.
3.
User ServletContext#getResourceAsStream
InputStream resourceStream = request.getSession().getServletContext().getResourceAsStream("/WEB-INF/jasper/" + fileName + ".jrxml");
This is an alternative of ServletContext#getResource
to get an inputSteam
UPDATE:
The URL return from ServletContext#getResource
may not be a file URL and it may cause issue. Please try ServletContext#getResourceAsStream
with JasperCompileManager#compileReportToFile
:
JasperDesign jasperDesign = JRXmlLoader.load(resourceStream);
JasperCompileManager.compileReportToFile(jasperDesign, jasperFilePath);
I found that your are trying to write jasper report file into your program distribution which should be avoid. The preferred way is to pre-compile your report and put into your WAR file or put the compiled jasper report into a temporary directory.
Following is full code example:
public JasperReport getCompiledFile(String fileName, HttpServletRequest request) throws JRException, IOException {
// Create temporary folder to store jasper report as you should not write a resource into your program
// distribution
String tempFolderPath = System.getProperty("java.io.tmpdir") + File.separator + "jasperReport";
File tempFolder = new File(tempFolderPath);
if (!tempFolder.exists()) {
tempFolder.mkdirs();
}
String jasperFilePath = tempFolderPath + File.separator + fileName + ".jasper";
File reportFile = new File(jasperFilePath);
// If compiled file is not found, then compile XML template
if (!reportFile.exists()) {
InputStream jRXmlStream = request.getSession().getServletContext().getResourceAsStream
("/WEB-INF/jasper/" + fileName + ".jrxml");
JasperDesign jasperDesign = JRXmlLoader.load(jRXmlStream);
JasperCompileManager.compileReportToFile(jasperDesign, jasperFilePath);
}
JasperReport jasperReport = (JasperReport) JRLoader.loadObjectFromFile(reportFile.getPath());
return jasperReport;
}