Передача содержимого при создании отчета JasperServer с использованием REST API - PullRequest
9 голосов
/ 10 января 2012

Я работаю над проектом, целью которого является замена нашего текущего генератора PDF на JasperReports Server.Планируется использовать API REST / HTTP для достижения высокого уровня абстракции между системами.

Оптимально, мы не хотим, чтобы сервер JasperReports извлекал данные из базы данных, поскольку это могло бы обойти существующиерегистрация и авторизация в архитектуре вызывающего приложения.Вместо этого мы хотели бы начать с извлечения контента в вызывающем приложении, а затем передать его на сервер JasperReports.

Мы провели немало исследований, и отсутствие соответствующих результатов указывает на то, чтоэто не то, как вы обычно используете JasperReports Server.Входные параметры в найденных нами руководствах обычно представляют собой скалярные значения (целые числа, логические значения или строки), а не сложные структуры или объекты.Кроме того, кажется, что более или менее каждый пример предполагает, что вы хотите разрешить JasperReports Server подключаться к базе данных.

Если возможно передать сложные структуры (например, массив карт, где некоторые элементы карты являются массивамиили сами карты), что лучше для этого делать?Я понятия не имею, как такая структура должна быть отформатирована в теле запроса.Является ли SOAP API более подходящим?

Если это совсем не то, как вам следует разрабатывать решение JasperReports Server, какие альтернативные продукты / решения больше подходят?

Заранее спасибо за любой вклад.

Ответы [ 3 ]

8 голосов
/ 17 января 2012

После нескольких часов, потраченных на исследования, я думаю, что готов ответить на свой вопрос.

Сервер JasperReports («JRS» ниже) в основном предназначен для самостоятельного извлечения данных. Хотя было бы возможно принудительно кормить JRS данными, я решил этого не делать.

Один из наиболее очевидных недостатков, заключающийся в том, что JRS не может извлекать сами данные, состоит в том, что создание веб-интерфейса JRS более невозможно. Интеграция с другими системами также становится невозможной или трудной, если клиентское приложение отвечает за предоставление данных в предопределенном формате.

В проекте, над которым я работаю, мы решили создать собственный JRS DataSource на основе Remote XML DataSource, который вызывает XML API клиентского приложения. Другими словами, клиентское приложение запрашивает отчет из JRS, а затем JRS запрашивает данные из клиентского приложения. XML API придется расширить, чтобы покрыть все наши потребности в отчетности, но, на мой взгляд, это хорошая вещь. Хорошее покрытие API пригодится в будущем.

Я надеюсь, что эти мысли помогут кому-то, у кого есть подобные вопросы.

1 голос
/ 12 октября 2017

Как вы писали, выборка данных является более естественным способом для JRS. Однако мне нужно было пойти противоположным путем - я отправляю данные POST, чтобы сообщить о работе в репозитории JRS с помощью вызова REST.

Я передаю данные XML в своем параметре "xmlDocument", и с помощью "трюка" исполняемый отчет может использовать этот 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_INPUT_STREAM появился после выбора адаптера XML.

Затем я публикую отчет в 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.

0 голосов
/ 04 июня 2019

Даже если я согласен с ответом, ведьма заявляет, что JasperServer был создан для извлечения данных сам по себе, мне все равно приходилось передавать данные через остальной API, потому что это унаследованный для моей компании способ создания отчетов Jasper и потому что мы хотим использовать пользовательские сервисы Java для извлечения данных.

Я обнаружил, что описанное выше является самым простым способом сделать это.

Имея это простое пользовательское ПО, которое вы хотите передать в отчет через веб-API:

public class CustomReport {

private String content;

public String getContent() {
    return content;
}

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

public CustomReport() {
    super();
}

1) Определите пользовательский скриптлет jasper, который должен быть развернут на сервере в качестве ресурса, связанного с отчетом. Ведьма десериализует строку в пользовательский объект pojo, используя GSON:

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) Используйте параметр / переменную с пользовательским скриптлетом на сервере jasper:

<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\" } "]
        }
    ]
}
...