My next step in learning how to use JasperReports, is to integrate JasperReports into a Struts2 web application. There is a Struts2 JasperReports plugin (refer 1) that is part of the Struts2 download. Look for the jar named "struts2-jasperreports-plugin-126.96.36.199.jar" in the struts-188.8.131.52\lib directory.
Using the Struts2 JasperReports plugin it's relatively easy to integrate JasperReports into your web application. There are a couple of changes you'll need to make to the master report if you're using a subreport. The changes you need to make are not well documented as it took me several hours of trouble shooting to figure it out. Luckily, Dave Newton, a Struts2 - JasperReports plugin expert, kindly explained to me what I was doing wrong.
I thought it would be a good idea to write the steps up in my blog to help others who are trying to use the Struts2 JasperReports plugin with a main report and subreport.
In the example application there is a Person class that has three attributes (firstName, lastName, and phones). The phones attribute is an ArrayList of Phone objects. The Phone class has two attributes (phoneNumber and phoneType).
In the previous example (refer. 2), I had a main report and a subreport. The subreport was used to display each Person's phone numbers and phone types. I'll be using those same reports for the web application.
I created a dynamic web application in Eclipse and brought in the Person and Phone classes (in package model). I then put all the Struts2 and JasperReport jar files into my web-inf/lib directory. I then created a simple Struts2 ActionSupport class that has an execute method that just returns success. This class also has a getBeanCollection method that returns an ArrayList of Person objects. This method will be used as the data source to fill the Jasper report with data.
Modify The Main JasperReport .jrxml File
The one important step that took me so much trouble to figure out (and thanks again to Dave Newton) is that you have to modify your main .jrxml file if you're using a subreport that is linked to the main report through a field that is an ArrayList (in this case the phones field of class Person).
First copy the struts2-jasperreports-plugin-184.108.40.206.jar to the lib folder that is under iReports (in my case this is "C:\Program Files\JasperSoft\iReport-3.0.0\lib"). Then start up iReport.
Open the main report, which in the example is contacts.jrxml. Select View - Fields, and then click on the phones field and click on modify.
Under Field Class Type enter: org.apache.struts2.views.jasperreports.ValueStackDataSource. This is a data type defined by the Struts2 JasperReports plugin. This data type will ensure the Collection type (phones) is exposed to the subreport by the Struts2 JasperReport plugin.
Click OK and close the fields window.
Next, right click on the subreport and select properties. Click on the Subreport tab and change this
(which is under Use data source expression) to this
The Struts2 JasperReport plugin will handle processing the phones ArrayList and make it available to the subreport.
Next click the Subreport (Other) tab and under Subreport Expression enter this:
(this is the location in your web application class path where the subreport can be located, so in my examples the subreport is under web-inf/classes/jasper). Then your web application will be able to find the subreport.
Close that window. Save the report and Build - Compile. Make sure your Options - Settings - Compiler is set to compile the report into the correct folder in your web application (in my example that is WebContent/Jasper).
Also make sure you've compiled the subreport and copied the subreport .jasper file into the correct folder in your web application (again in my example that is web-inf/classes/jasper).
In the struts2.xml I defined a package and action with the following code.
<package name="default" extends="jasperreports-default,struts-default">
<action name="myJasperTest" class="action.JasperAction">
<result name="success" type="jasper">
<result name="error" type="jasper">/Error.jsp</result>
Note the extends attribute value of the package node.
In the action's success result the type is set to jasper and three parameter values are passed. The location parameter specifies where to find the main report (in my example the main report is in /jasper/contacts.jasper from my web application's root directory. The dataSource parameter value is the getBeanCollection method (Struts2 calls the getBeanCollection method if you use the beanCollection value) in the ActionSupport class (found in action.JasperAction). This method returns an ArrayList of Person objects that are used to fill the JasperReport.
Lastly, the format parameter specifies the returned report format (eg PDF). Check out the plugin API (reference 1) for other report format types you can specify.
Hopefully, you'll be able to follow these guidelines to get your own Struts2 - JasperReports web application up and running. In the references section are links to the Struts2 mailing list and to the JasperReports forum. Searching those two resources may help you answer any questions.
- Struts2 JasperReports Plug In
- Bruce Phillips Blog, Using JasperReports With An ArrayList of Objects Part 2: Using the Report In A Java Application
- Working Example, Struts2 JasperReports Plug In, Main Report and Subreport
- Struts2 Mailing List
- JasperReports User Forum
- Download a complete war file of the example