JasperReports Ultimate Guide - Samples - Schema - Configuration - Functions - FAQ - API (Javadoc)
|
|
|
|
JasperReports - HTTP Data Adapter Sample (version 6.21.0) | |
|
|
|
Main Features in This Sample | |
| HTTP Data Adapter |
|
|
Secondary Features | |
JSONQL Data Source | |
XML Data Source |
|
|
||||||
top | |||||||
|
|||||||
HTTP Data Adapter | Documented by Sanda Zaharia | ||||||
|
|||||||
| Description / Goal |
| How to fill a report using data from an HTTP request returning XML or JSON file. | ||||
| Since |
| |||||
| Other Samples |
|
|
||||
|
|||||||
|
Accessing Data over HTTP
An HTTP data adapter is a data file-based data adapter that uses an HttpDataLocation object, in order to gain access to remote data over HTTP and retrieve content that can be mapped to a custom (usually JSONQL or XML) data source. DataFile-based adapters (such as JsonDataAdapter or XmlDataAdapter) can be converted into HTTP data adapters by declaring their DataFile element of type HttpDataLocation :
<jsonDataAdapter class="net.sf.jasperreports.data.json.JsonDataAdapterImpl"> <name>JSON Http Data Adapter</name> <dataFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="httpDataLocation"> ... </dataFile> ... </jsonDataAdapter>or <xmlDataAdapter class="net.sf.jasperreports.data.xml.XmlDataAdapterImpl"> <name>XML Http Data Adapter</name> <dataFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="httpDataLocation"> ... </dataFile> ... </xmlDataAdapter>The HttpDataLocation object encapsulates the following information, related to a given HTTP request:
None of the elements described above ( method , url , username , password , urlParameter ,
body , postParameter or header ) are required in an HTTP data adapter.
The only requirement is to have its type declared as httpDataLocation (xsi:type="httpDataLocation" ).
In case no method element is specified, the default method name depends on the presence/absence of the body element or the postParameter list:
url , username , urlParameter , etc), we can send all this information
via the usual report parameters, since data adapters are in fact parameter contributor objects.
The following predefined parameter properties let us configure the HTTP request, and always override the similar information declared in data adapter:
The information stored in the HttpDataLocation object is collected and processed by the
HttpDataService API, which builds a client object to
send a specific request over HTTP.
As a result, a data file connection is obtained in the form of an HttpDataConnection object. This object comes with an InputStream that can be extracted and interpreted as custom data source (usually in JSON or XML format), using the
available public methods of the class:
This sample provides 2 examples based on the HTTP data adapter: one of them will process the input in order to get a JSONQL data source, the other will prepare an XML data source by querying the same data. Following are the 2 data adapter definitions: Content of the JSON Data Adapter (see data/JsonHttpDataAdapter.jrdax file provided in this sample directory):
<jsonDataAdapter class="net.sf.jasperreports.data.json.JsonDataAdapterImpl"> <name>JSON Http Data Adapter</name> <dataFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="httpDataLocation"> <method>GET</method> <url><![CDATA[http://www.omdbapi.com/?r=json]] ></url> </dataFile> <useConnection>true</useConnection> <timeZone xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:java="http://java.sun.com" xsi:type="java:java.lang.String">Europe/Bucharest</timeZone> <locale xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:java="http://java.sun.com" xsi:type="java:java.lang.String">ro_RO</locale> <selectExpression></selectExpression> </jsonDataAdapter>Content of the XML Data Adapter (see data/XmlHttpDataAdapter.jrdax file provided in this sample directory):
<xmlDataAdapter class="net.sf.jasperreports.data.xml.XmlDataAdapterImpl"> <name>XML Http Data Adapter</name> <dataFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="httpDataLocation"> <method>GET</method> <url><![CDATA[http://www.omdbapi.com/?r=xml]] ></url> </dataFile> <useConnection>true</useConnection> <timeZone xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:java="http://java.sun.com" xsi:type="java:java.lang.String">Europe/Bucharest</timeZone> <locale xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:java="http://java.sun.com" xsi:type="java:java.lang.String">ro_RO</locale> <selectExpression></selectExpression> </xmlDataAdapter>We can observe that the above data adapters are quite similar:
The JRXML files The JRXML files are found in the reports folder of this JasperReports sample.
Like the above data adapters, they look almost similar, the only differences being related to data adapter type, query language and dataset field properties (because these are also related to the query language). Each JRXML report
<jasperReport ... name="JsonHttpDataAdapterReport" ...> <property name="net.sf.jasperreports.data.adapter" value="data/JsonHttpDataAdapter.jrdax"/> <subDataset name="FetchDataset" uuid="753275b1-35e7-428e-87be-88a1863e1c06"> <parameter name="title" class="java.lang.String"/> </subDataset> <subDataset name="MoviesDataset" uuid="bb6eeca6-9992-4268-8570-db12d8d5c79d"> <property name="net.sf.jasperreports.data.adapter" value="data/JsonHttpDataAdapter.jrdax"/> <parameter name="title" class="java.lang.String"> <property name="net.sf.jasperreports.http.data.url.parameter" value="s"/> </parameter> <parameter name="page" class="java.lang.Integer"> <property name="net.sf.jasperreports.http.data.url.parameter"/> </parameter> <queryString language="jsonql"> <![CDATA[Search]] > </queryString> <field name="title" class="java.lang.String"> <property name="net.sf.jasperreports.jsonql.field.expression" value="Title"/> </field> <field name="year" class="java.lang.Integer"> <property name="net.sf.jasperreports.jsonql.field.expression" value="Year"/> </field> <field name="type" class="java.lang.String"> <property name="net.sf.jasperreports.jsonql.field.expression" value="Type"/> </field> <field name="poster" class="java.lang.String"> <property name="net.sf.jasperreports.jsonql.field.expression" value="Poster"/> </field> </subDataset> <parameter name="title" class="java.lang.String" evaluationTime="Early"> <property name="net.sf.jasperreports.http.data.url.parameter" value="s"/> <defaultValueExpression><![CDATA["aliens"]] ></defaultValueExpression> </parameter> <queryString language="jsonql"> <![CDATA[]] > </queryString> <field name="totalResults" class="java.lang.Integer"> <property name="net.sf.jasperreports.jsonql.field.expression" value="totalResults"/> </field> ... </jasperReport>Both the main dataset and MoviesDataset require information from JsonHttpDataAdapter.jrdax file
via net.sf.jasperreports.data.adapter property.
In the main dataset we have a report parameter named title that will serve also as HTTP request URL parameter,
as specified by the net.sf.jasperreports.http.data.url.parameter property:
<parameter name="title" class="java.lang.String" evaluationTime="Early"> <property name="net.sf.jasperreports.http.data.url.parameter" value="s"/> <defaultValueExpression><![CDATA["aliens"]] ></defaultValueExpression> </parameter>We see that this property has a value, and the value is s .
It means that an URL parameter will be appended to the base request URL, with the name s and the default value aliens (as stated in <defaultValueExpression/> ).
With these settings, the web service URL will look like: http://www.omdbapi.com/?r=json&s=aliens
In response the web service will return a JSON object in the following format: { "Search":[ {"Title":"Aliens","Year":"1986","imdbID":"tt0090605","Type":"movie","Poster":"https://.../...jpg"}, {"Title":"Cowboys & Aliens","Year":"2011","imdbID":"tt0409847","Type":"movie","Poster":"https://.../...jpg"}, ... ], "totalResults":"213", "Response":"True" }Here we have
"totalResults" number, in order to use it in the page header.
To get it, we declared the report query language as jsonql , and set a related report field named totalResults
as follows:
<queryString language="jsonql"> <![CDATA[]] > </queryString> <field name="totalResults" class="java.lang.Integer"> <property name="net.sf.jasperreports.jsonql.field.expression" value="totalResults"/> </field>One can observe the associated net.sf.jasperreports.jsonql.field.expression property that links the totalResults
field name to the "totalResults" number provided by the JSON object.
MoviesDataset comes with 2 dataset parameters, which are related to request URL parameters via properties:
<parameter name="title" class="java.lang.String"> <property name="net.sf.jasperreports.http.data.url.parameter" value="s"/> </parameter> <parameter name="page" class="java.lang.Integer"> <property name="net.sf.jasperreports.http.data.url.parameter"/> </parameter>The title parameter with the value s is the same as discussed above. The second parameter
named page adds pagination (each page contains by default 10 results) to the request URL.
The net.sf.jasperreports.http.data.url.parameter
property has no value in this case, meaning that the name of the appended URL parameter is also page .
Since there is no default value for this parameter, its value will be provided during report execution at runtime. With these settings, for the second page of results, the web service URL will look like: http://www.omdbapi.com/?r=json&s=aliens&page=2
Note: The http://www.omdbapi.com/?r=json&s=aliens request URL has the same effect as
http://www.omdbapi.com/?r=json&s=aliens&page=1
The query language in MovieDataset is also jsonql , but now we perform a JSONQL query on the
"Search" array member of the JSON object, in order to retrieve the movie information regarding title, year, movie type and
poster:
<queryString language="jsonql"> <![CDATA[Search]] > </queryString> <field name="title" class="java.lang.String"> <property name="net.sf.jasperreports.jsonql.field.expression" value="Title"/> </field> <field name="year" class="java.lang.Integer"> <property name="net.sf.jasperreports.jsonql.field.expression" value="Year"/> </field> <field name="type" class="java.lang.String"> <property name="net.sf.jasperreports.jsonql.field.expression" value="Type"/> </field> <field name="poster" class="java.lang.String"> <property name="net.sf.jasperreports.jsonql.field.expression" value="Poster"/> </field>Here we have parameter properties with case sensitive values. For instance, the title report field is
linked to the "Title" member of the JSON object representing the movie information in the "Search" array.
All these fields are used in a list component that uses the MovieDataset as dataset, based on title
and page parameter values:
<jr:list printOrder="Vertical"> <datasetRun subDataset="MoviesDataset" uuid="134b029e-9e8b-401f-9bd1-2a6087ea1242"> <datasetParameter name="title"> <datasetParameterExpression><![CDATA[$P{title}]] ></datasetParameterExpression> </datasetParameter> <datasetParameter name="page"> <datasetParameterExpression><![CDATA[$V{REPORT_COUNT}]] ></datasetParameterExpression> </datasetParameter> </datasetRun> <jr:listContents height="65" width="170"> ... </jr:listContents> </jr:list>The other subdataset in the report (i.e FetchDataset ) is used in conjunction with an empty data source, in order to allow
paginated results to be rendered page by page during the report execution.
It contains a report parameter named title that will be collected from the main dataset at runtime:
<detail> <band height="65" splitType="Stretch"> <componentElement> <reportElement x="0" y="0" width="170" height="65" uuid="a7ece49e-f10a-43eb-8c09-86353ba9225d"/> <jr:list ... printOrder="Vertical"> <datasetRun subDataset="FetchDataset" uuid="61c31d0f-e3b3-46c6-a11a-8c5d8b7016cf"> <datasetParameter name="title"> <datasetParameterExpression><![CDATA[$P{title}]] ></datasetParameterExpression> </datasetParameter> <dataSourceExpression><![CDATA[new JREmptyDataSource((int)(Math.ceil($F{totalResults} / 10d)))]] ></dataSourceExpression> </datasetRun> <jr:listContents height="65" width="170"> <componentElement> ... </componentElement> </jr:listContents> </jr:list> </componentElement> </band> </detail>As already stated, the XmlHttpDataAdapterReport.jrxml file looks similar to JsonHttpDataAdapterReport.jrxml file. Report parameters definitions are the same in both JRXML files. Query languages and dataset field definitions are slightly different. Following are presented the main differences exposed by XmlHttpDataAdapterReport.jrxml: <jasperReport name="XmlHttpDataAdapterReport" ...> <property name="net.sf.jasperreports.data.adapter" value="data/XmlHttpDataAdapter.jrdax"/> <subDataset name="FetchDataset" uuid="753275b1-35e7-428e-87be-88a1863e1c06"> <parameter name="title" class="java.lang.String"/> </subDataset> <subDataset name="MoviesDataset" uuid="bb6eeca6-9992-4268-8570-db12d8d5c79d"> <property name="net.sf.jasperreports.data.adapter" value="data/XmlHttpDataAdapter.jrdax"/> <parameter name="title" class="java.lang.String"> <property name="net.sf.jasperreports.http.data.url.parameter" value="s"/> </parameter> <parameter name="page" class="java.lang.Integer"> <property name="net.sf.jasperreports.http.data.url.parameter"/> </parameter> <queryString language="xPath"> <![CDATA[/root/result]] > </queryString> <field name="title" class="java.lang.String"> <property name="net.sf.jasperreports.xpath.field.expression" value="@title"/> </field> <field name="year" class="java.lang.Integer"> <property name="net.sf.jasperreports.xpath.field.expression" value="@year"/> </field> <field name="type" class="java.lang.String"> <property name="net.sf.jasperreports.xpath.field.expression" value="@type"/> </field> <field name="poster" class="java.lang.String"> <property name="net.sf.jasperreports.xpath.field.expression" value="@poster"/> </field> </subDataset> <parameter name="title" class="java.lang.String" evaluationTime="Early"> <property name="net.sf.jasperreports.http.data.url.parameter" value="s"/> <defaultValueExpression><![CDATA["aliens"]] ></defaultValueExpression> </parameter> <queryString language="xPath"> <![CDATA[/root]] > </queryString> <field name="totalResults" class="java.lang.Integer"> <property name="net.sf.jasperreports.xpath.field.expression" value="@totalResults"/> </field> ... </jasperReport>
<field name="totalResults" class="java.lang.Integer"> <property name="net.sf.jasperreports.xpath.field.expression" value="@totalResults"/> </field>and in MoviesDataset :
<field name="title" class="java.lang.String"> <property name="net.sf.jasperreports.xpath.field.expression" value="@title"/> </field> <field name="year" class="java.lang.Integer"> <property name="net.sf.jasperreports.xpath.field.expression" value="@year"/> </field> <field name="type" class="java.lang.String"> <property name="net.sf.jasperreports.xpath.field.expression" value="@type"/> </field> <field name="poster" class="java.lang.String"> <property name="net.sf.jasperreports.xpath.field.expression" value="@poster"/> </field>Running the Sample Running the sample requires the Apache Ant library. Make sure that ant is already installed on your system (version 1.5 or later).
In a command prompt/terminal window set the current folder to demo/samples/httpdataadapter within the JasperReports source distro and run the > ant test view command.
It will generate all supported document types containing the sample report in the demo/samples/httpdataadapter/build/reports directory.
Then the report generated from JsonHttpDataAdapterReport.jrxml file will open in the JasperReports internal viewer.
|
||||||
|
|
© 2001- Cloud Software Group, Inc. www.jaspersoft.com |