Java 如何用JasperReportsContext替换JRParameter.REPORT\U FILE\U解析器的使用?
JR参数.REPORT\u FILE\u解析器在5.0版中不推荐使用。 Javadoc建议改用JasperReportsContext 如何使用JasperReportsContext 使用Struts2 jasper插件时需要使用Java 如何用JasperReportsContext替换JRParameter.REPORT\U FILE\U解析器的使用?,java,struts2,jasper-reports,Java,Struts2,Jasper Reports,JR参数.REPORT\u FILE\u解析器在5.0版中不推荐使用。 Javadoc建议改用JasperReportsContext 如何使用JasperReportsContext 使用Struts2 jasper插件时需要使用 connection=dataSource.getConnection(); reportParams.put(JRParameter.REPORT_FILE_RESOLVER, new SimpleFileResolver(reportsDir)); 我也有同样
connection=dataSource.getConnection();
reportParams.put(JRParameter.REPORT_FILE_RESOLVER, new SimpleFileResolver(reportsDir));
我也有同样的问题(),几个小时后,我在JasperReports的资料中找到了答案
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);
编辑:
正确的解决方案包括向插件的项目票务系统报告问题,并可能为解析器实现提供补丁
在等待补丁被接受时,您可以扩展JasperReportsResult
类,只需使用上面的代码覆盖doExecute()
方法,如下所示:
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);
}
然后在Struts中使用新扩展作为结果。请测试该方法是否正确实现
最终的解决方案应该包括在结果对象上使用上下文实例设置器,或者可以从结果对象访问全局静态上下文实例。我的问题(这么长)不太好。我使用jasper struts2插件,您需要传递参数(struts自己管理填充和导出操作)。我向struts传递了一个hashmap参数。在这个hashmap中,我放置了我的参数和文件解析器:reportParams.put(JRParameter.REPORT_FILE_RESOLVER,new SimpleFileResolver(reportsDir));这就是我不想取代的东西。@Rydermark但这个问题的答案是正确的,不是吗?不幸的是,不,或者我不知道怎么做。也许你能更精确地描述一些事情。@Rydermark现在更明显了吗?您必须将文件解析器传递到上下文,而不是将其填充到
reportParams
。仍然不能。这个问题非常特定于Struts2 jasper插件,您不需要构建上下文。“以正常方式”生成ByteArrayOutputStream没有任何问题。使用插件时无法访问上下文。您只有参数映射、连接和报告的位置。非常感谢您的努力。请看下面的图片。你可以打开一个问题。