Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Had the same problem (<a href="https://stackoverflow.com/questions/15004325/file-resolver-in-jasper-reports-5-0-1/15023748#15023748">File resolver in Jasper Reports 5.0.1</a>) and after many hours I found the answer in the JasperReports sources.</p> <pre><code>LocalJasperReportsContext ctx = new LocalJasperReportsContext(DefaultJasperReportsContext.getInstance()); ctx.setClassLoader(getClass().getClassLoader()); ctx.setFileResolver(new FileResolver() { @Override public File resolveFile(String s) { return new File(s); } }); JasperReport jasperReport = (JasperReport) JRLoader.loadObject(jasperfile); JasperFillManager fillmgr = JasperFillManager.getInstance(ctx); JasperExportManager exmgr = JasperExportManager.getInstance(ctx); </code></pre> <p><strong>Edit:</strong> The proper solution would include reporting the problem to the plugin's project ticketing system and maybe propose a patch for the resolver implementation.</p> <p>While waiting for the patch to get accepted, you can extend the <code>JasperReportsResult</code> class and just override the <code>doExecute()</code> method, using the code above, with something like this:</p> <pre><code>protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception { // Will throw a runtime exception if no "datasource" property. TODO Best place for that is...? initializeProperties(invocation); LOG.debug("Creating JasperReport for dataSource = {}, format = {}", dataSource, format); HttpServletRequest request = (HttpServletRequest) invocation.getInvocationContext().get(ServletActionContext.HTTP_REQUEST); HttpServletResponse response = (HttpServletResponse) invocation.getInvocationContext().get(ServletActionContext.HTTP_RESPONSE); // Handle IE special case: it sends a "contype" request first. // TODO Set content type to config settings? if ("contype".equals(request.getHeader("User-Agent"))) { try (OutputStream outputStream = response.getOutputStream()) { response.setContentType("application/pdf"); response.setContentLength(0); } catch (IOException e) { LOG.error("Error writing report output", e); throw new ServletException(e.getMessage(), e); } return; } // Construct the data source for the report. ValueStack stack = invocation.getStack(); ValueStackDataSource stackDataSource = null; Connection conn = (Connection) stack.findValue(connection); if (conn == null) stackDataSource = new ValueStackDataSource(stack, dataSource, wrapField); if ("https".equalsIgnoreCase(request.getScheme())) { // set the the HTTP Header to work around IE SSL weirdness response.setHeader("CACHE-CONTROL", "PRIVATE"); response.setHeader("Cache-Control", "maxage=3600"); response.setHeader("Pragma", "public"); response.setHeader("Accept-Ranges", "none"); } // Determine the directory that the report file is in and set the reportDirectory parameter // For WW 2.1.7: // ServletContext servletContext = ((ServletConfig) invocation.getInvocationContext().get(ServletActionContext.SERVLET_CONFIG)).getServletContext(); ServletContext servletContext = (ServletContext) invocation.getInvocationContext().get(ServletActionContext.SERVLET_CONTEXT); String systemId = servletContext.getRealPath(finalLocation); Map parameters = new ValueStackShadowMap(stack); File directory = new File(systemId.substring(0, systemId.lastIndexOf(File.separator))); parameters.put("reportDirectory", directory); parameters.put(JRParameter.REPORT_LOCALE, invocation.getInvocationContext().getLocale()); // put timezone in jasper report parameter if (timeZone != null) { timeZone = conditionalParse(timeZone, invocation); final TimeZone tz = TimeZone.getTimeZone(timeZone); if (tz != null) { // put the report time zone parameters.put(JRParameter.REPORT_TIME_ZONE, tz); } } // Add any report parameters from action to param map. Map reportParams = (Map) stack.findValue(reportParameters); if (reportParams != null) { LOG.debug("Found report parameters; adding to parameters..."); parameters.putAll(reportParams); } ByteArrayOutputStream output; JasperPrint jasperPrint; LocalJasperReportsContext ctx = new LocalJasperReportsContext(DefaultJasperReportsContext.getInstance()); ctx.setClassLoader(getClass().getClassLoader()); ctx.setFileResolver(parameters.get()); JasperReport jasperReport = (JasperReport) JRLoader.loadObject(jasperfile); JasperFillManager fillmgr = JasperFillManager.getInstance(ctx); JasperExportManager exmgr = JasperExportManager.getInstance(ctx); // Fill the report and produce a print object try { JasperReport jasperReport = (JasperReport) JRLoader.loadObject(new File(systemId)); if (conn == null) { jasperPrint = fillmgr.fillReport(jasperReport, parameters, stackDataSource); } else { jasperPrint = fillmgr.fillReport(jasperReport, parameters, conn); } } catch (JRException e) { LOG.error("Error building report for uri {}", systemId, e); throw new ServletException(e.getMessage(), e); } // Export the print object to the desired output format try { if (contentDisposition != null || documentName != null) { final StringBuffer tmp = new StringBuffer(); tmp.append((contentDisposition == null) ? "inline" : contentDisposition); if (documentName != null) { tmp.append("; filename="); tmp.append(documentName); tmp.append("."); tmp.append(format.toLowerCase()); } response.setHeader("Content-disposition", tmp.toString()); } JRExporter exporter; if (format.equals(FORMAT_PDF)) { response.setContentType("application/pdf"); exporter = new JRPdfExporter(ctx); } else if (format.equals(FORMAT_CSV)) { response.setContentType("text/csv"); exporter = new JRCsvExporter(ctx); } else if (format.equals(FORMAT_HTML)) { response.setContentType("text/html"); // IMAGES_MAPS seems to be only supported as "backward compatible" from JasperReports 1.1.0 Map imagesMap = new HashMap(); request.getSession(true).setAttribute("IMAGES_MAP", imagesMap); exporter = new JRHtmlExporter(ctx); exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, imagesMap); exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, request.getContextPath() + imageServletUrl); // Needed to support chart images: exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); request.getSession().setAttribute("net.sf.jasperreports.j2ee.jasper_print", jasperPrint); } else if (format.equals(FORMAT_XLS)) { response.setContentType("application/vnd.ms-excel"); exporter = new JRXlsExporter(ctx); } else if (format.equals(FORMAT_XML)) { response.setContentType("text/xml"); exporter = new JRXmlExporter(ctx); } else if (format.equals(FORMAT_RTF)) { response.setContentType("application/rtf"); exporter = new JRRtfExporter(ctx); } else { throw new ServletException("Unknown report format: " + format); } Map exportParams = (Map) stack.findValue(exportParameters); if (exportParams != null) { LOG.debug("Found export parameters; adding to exporter parameters..."); exporter.getParameters().putAll(exportParams); } output = exportReportToBytes(jasperPrint, exporter); } catch (JRException e) { LOG.error("Error producing {} report for uri {}", format, systemId, e); throw new ServletException(e.getMessage(), e); } finally { try { conn.close(); } catch (Exception e) { LOG.warn("Could not close db connection properly", e); } } response.setContentLength(output.size()); // Will throw ServletException on IOException. writeReport(response, output); } </code></pre> <p>and than use the new extension as the <strong>Result</strong> in Struts. Please test if the method is implemented correctly.</p> <p>The final solution should include the use of a context instance setter on the Result object, or maybe a global static context instance accessible from the Result object.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload