10

我正在开发一个项目,旨在用 JasperReports Server 替换我们当前的 PDF 生成器。计划是使用 REST/HTTP API 来达到系统之间的高级抽象。

最理想的情况是,我们不想让 JasperReports Server 从数据库中提取数据,因为这会绕过调用应用程序架构中现有的日志记录和授权。相反,我们希望先在调用应用程序中提取内容,然后将该内容传递给 JasperReports Server。

我们进行了相当多的调查,缺乏相关结果表明这不是您通常使用 JasperReports Server 的方式。我们发现的教程中的输入参数通常是标量值(整数、布尔值或字符串),而不是复杂的结构或对象。此外,似乎每个示例或多或少都假设您希望让 JasperReports Server 连接到数据库。

如果可以传入复杂的结构(例如地图数组,其中一些地图元素是数组或地图本身),那么这样做的最佳做法是什么?我不知道应该如何在请求正文中格式化这样的结构。SOAP API 是否更合适?

如果这根本不是您应该如何设计 JasperReports 服务器解决方案,那么有哪些替代产品/解决方案更合适?

提前感谢您的任何意见。

4

3 回答 3

8

经过几个小时的研究,我想我已经准备好回答我自己的问题了。

JasperReports Server(以下简称“JRS”)从根本上设计为自行获取数据。尽管可以强制向 JRS 提供数据,但我决定不这样做。

不让 JRS 自己获取数据的最明显缺点之一是不再可能从 JRS Web 界面生成报告。如果客户端应用程序负责以预定义格式提供数据,那么与其他系统的集成也变得不可能或困难。

在我正在进行的项目中,我们决定构建一个基于远程 XML 数据源的自定义 JRS 数据源,它调用客户端应用程序的 XML API。换句话说,客户端应用程序从 JRS 请求报告,然后 JRS 从客户端应用程序请求它的数据。XML API 必须扩展以涵盖我们所有的报告需求,但在我看来这是一件好事。良好的 API 覆盖率将在未来派上用场。

我希望这些想法可以帮助有类似问题的人。

于 2012-01-16T21:36:39.233 回答
1

正如您所写,获取数据对于 JRS 来说是更自然的方式。但是,我需要采取相反的方式——我通过 REST 调用发布数据以报告坐在 JRS 存储库中。

我在参数“xmlDocument”中传递 XML 数据,并且通过“技巧”,执行的报告可以使用该 XML 进行进一步的 X-path 查询。

xmlDocument 只是一个简单的字符串:

<parameter name="xmlDocument" class="java.lang.String">
    <defaultValueExpression><![CDATA["<?xml version=\"1.0\" encoding=\"UTF-8\"?><documentData></documentData>"]]></defaultValueExpression>
</parameter>

在设计阶段,我使用用于预览的 XML 文件创建 XML 数据适配器。请注意,选择 XML 适配器后会出现一个新参数 XML_INPUT_STREAM。

然后我将报告发布到 JRS。在报表执行期间,当报表未链接到任何数据源时,它会改为读取 XML_INPUT_STREAM 参数(作为备用数据源),如下所示:

<parameter name="XML_INPUT_STREAM" class="java.io.InputStream" isForPrompting="false">
    <defaultValueExpression><![CDATA[new java.io.ByteArrayInputStream($P{xmlDocument}.getBytes("UTF-8"))]]></defaultValueExpression>
</parameter>

我将“xmlDocument”字符串包装到 InputStream。

于 2017-10-12T08:36:29.953 回答
0

即使我同意这个答案,witch 说 JasperServer 已经被构建为自行获取数据,我仍然必须通过其余 API 传递数据,因为这是我公司构建 Jasper 报告的传统方式,因为我们想要使用自定义 Java 服务来获取数据。

我发现上面描述的这是最简单的方法。

拥有您想要通过 Web API 传递给报告的简单自定义 pojo:

public class CustomReport {

private String content;

public String getContent() {
    return content;
}

public void setContent(String content) {
    this.content = content;
}

public CustomReport() {
    super();
}

1) 定义一个必须部署在服务器上的自定义 jasper scriptlet 作为与报告相关的资源,Witch 将使用 GSON 将字符串反序列化为自定义 pojo 对象:

public class CustomScriptlet
    extends JRDefaultScriptlet { public void afterReportInit()
        throws JRScriptletException
{
    Object customSerializedObj = getParameterValue("customSerialized");
    if (customSerializedObj != null)
    {
        String customSerializedStr = customSerializedObj.toString();
        if ((customSerializedStr != null) && (customSerializedStr.length() > 0))
        {
            CustomReport customReport = new Gson().fromJson(customSerializedStr,
                            CustomReport.class);

            setVariableValue("customReport", customReport);
        }
    }
}

2)使用参数/变量与碧玉服务器中的自定义脚本:

<scriptlet name="Scriptlet_1" class="eu.dedalus.jasper.api.scriptlet.CustomScriptlet">
    <scriptletDescription><![CDATA[CustomScriptlet]]></scriptletDescription>
</scriptlet>
<parameter name="customSerialized" class="java.lang.String"/>
<variable name="customReport" class="com.test.CustomReport" calculation="System"/>

3)像这样调用API@jasperserver/rest_v2/reportExecutions:

    "reportUnitUri" : "/report/Custom_report",
"async":"false",
"outputFormat":"pdf",
"parameters" : {
    "reportParameter" : [
        {
            "name": "customReport",
            "value": ["{ \"content\" : \"test content\" } "]
        }
    ]
}
于 2019-06-04T12:56:04.263 回答