Spring4升级Spring5时JasperReports项目迁移问题求助
解决Spring 5.x移除JasperReports视图支持的替代方案
嘿,你遇到的这个问题很典型——Spring 5.x确实移除了org.springframework.web.servlet.view.jasperreports包下的所有视图类,官方给出的原因是要减少框架的冗余依赖,把这类第三方集成的工作交给开发者自己处理。不过别担心,有两个非常实用的替代方案:
方案一:直接使用JasperReports原生API生成PDF
这个方案最直接,跳过Spring的视图封装,在Controller里直接调用Jasper的API完成PDF生成和输出,灵活性更高。
示例代码如下:
import net.sf.jasperreports.engine.*; import net.sf.jasperreports.engine.export.JRPdfExporter; import net.sf.jasperreports.export.SimpleExporterInput; import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.util.HashMap; import java.util.Map; @RestController public class ReportController { private final ResourceLoader resourceLoader; public ReportController(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } @GetMapping("/purchase-pdf") public void generatePurchasePdf(HttpServletResponse response) throws Exception { // 1. 加载jrxml文件 Resource resource = resourceLoader.getResource("classpath:reports/purchaseReport.jrxml"); InputStream inputStream = resource.getInputStream(); // 2. 编译报表模板 JasperReport jasperReport = JasperCompileManager.compileReport(inputStream); // 3. 准备报表参数和数据源(对应原来的reportDataKey="datasource") Map<String, Object> parameters = new HashMap<>(); JRDataSource dataSource = // 这里传入你的数据源,比如JREmptyDataSource、JRBeanCollectionDataSource等 // 4. 填充报表数据 JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource); // 5. 输出PDF到响应 response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "attachment; filename=\"purchaseReport.pdf\""); JRPdfExporter exporter = new JRPdfExporter(); exporter.setExporterInput(new SimpleExporterInput(jasperPrint)); exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(response.getOutputStream())); exporter.exportReport(); } }
方案二:自定义Spring View实现(兼容原有视图解析逻辑)
如果想保留原来的XML视图配置风格,你可以自己实现一个View类,模仿原来JasperReportsPdfView的功能,这样不需要大幅修改现有代码结构。
步骤1:自定义Jasper PDF View类
import net.sf.jasperreports.engine.*; import net.sf.jasperreports.engine.export.JRPdfExporter; import net.sf.jasperreports.export.SimpleExporterInput; import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.web.servlet.view.AbstractView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; public class CustomJasperReportsPdfView extends AbstractView { private String url; // 对应原来的p:url属性 private String reportDataKey = "datasource"; // 对应原来的p:reportDataKey属性 private final ResourceLoader resourceLoader; public CustomJasperReportsPdfView(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; setContentType("application/pdf"); } @Override protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { // 加载并编译报表模板 Resource resource = resourceLoader.getResource(url); JasperReport jasperReport = JasperCompileManager.compileReport(resource.getInputStream()); // 获取数据源 JRDataSource dataSource = (JRDataSource) model.get(reportDataKey); // 填充报表 JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, model, dataSource); // 输出PDF response.setHeader("Content-Disposition", "attachment; filename=\"report.pdf\""); JRPdfExporter exporter = new JRPdfExporter(); exporter.setExporterInput(new SimpleExporterInput(jasperPrint)); exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(response.getOutputStream())); exporter.exportReport(); } // 提供setter方法供XML配置使用 public void setUrl(String url) { this.url = url; } public void setReportDataKey(String reportDataKey) { this.reportDataKey = reportDataKey; } }
步骤2:修改XML视图配置
把原来的JasperReportsPdfView替换成你自定义的类:
<!-- jasper-view.xml --> <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-5.2.xsd"> <bean id="purchasePdf" class="com.yourpackage.CustomJasperReportsPdfView" p:url="classpath:reports/purchaseReport.jrxml" p:reportDataKey="datasource" /> </beans>
注意要把com.yourpackage替换成你实际的包路径,同时确保ResourceLoader能被Spring自动注入(Spring 5.x会自动识别构造函数中的依赖)。
额外注意事项
- 确保你的
jasperreports依赖版本(6.4.0)兼容Java 11和Spring 5.2.5.RELEASE,这个版本是没问题的。 - 如果报表模板不需要动态编译,可以提前编译成
.jasper文件,然后直接加载编译后的文件,提升性能:JasperCompileManager.compileReportToFile(inputStream, "purchaseReport.jasper"),后续用JasperFillManager.fillReport("purchaseReport.jasper", parameters, dataSource)加载。
内容的提问来源于stack exchange,提问作者B378
相关产品推荐
相关产品推荐

