An important requirement in a lot of applications is reporting. It can be internal reports (same application jsp/html) or to an external format like xls,pdf or xml etc. A popular reporting engine is JasperReports. In the past few months I have seen a common posting theme in Spring Community Forums (even asking me via email) related about integration between JasperReports with Spring Web MVC and Spring Web Flow (SWF) and especially with Hibernate
A common architectural pattern is Model-View-Controller (MVC). A situation would be as follows:
Some user from the View layer (jsp/html) would click some button to request a desired report (i.e pdf,xls); the request should be handled in the Controller layer ( a controller class for Spring Web MVC or Action class for SWF), the controller/Action should call the Model layer(Service/BO) to delegate its work in that layer. The Service/BO would call DAO classes to get some data (rows from the database to fill and generate the report). After that, the Service/BO should send the report back to the Controller layer which should then send the report to the View layer.
Furthermore, a common approach when you work with Spring is to use Hibernate. If you work with Hibernate, we are using POJO classes to represent our entities, or instance Customer, Provider, etc. A simple report would be a list of all our Customers and other perhaps all our Providers, then, it logical working with a list (i.e. ArrayList) for these entities.
In my experience,many applications require some complex reports. For instance, maybe a special report required by your boss. After some analysis, you can conclude that a solution would be the result of do a query in the database working with two to six entities related (or even worst not related!). Here Hibernate would be not so useful, so the classic SQL query syntax is required (JOIN clause in this case) - you can use jdbcTemplate instead of Hibernate here.
Now suppose that for these six tables, each one has twenty fields and for your report you only need four fields of each table, then we have another problem. You are retrieving a lot of fields that you don't need. I used to work with my own wrap classes, now the question would be, how do I know what fields or variables I must create for my wrapclass?. The solution is this, from your yourreport.jrxml, open it and you must see something like (about structure)
<field name="idCustomer" class="java.lang.String"/> <field name="nameCustomer" class="java.lang.String"/> <field name="phoneCustomer" class="java.lang.String"/>
Dont forget that you can design your own reports using the IReport tool. Then when you write your own sql statements (with/inside IReport of course) to test your reports, in the same time implicitly in a dynamic way, you are creating a "<field..." for each field retrieved from the query. Each field should be a variable in your wrap class
For this example and for tutorial purposes I will create a simple wrap class and avoid the DB connection. Before we start consider these situations:
- If you are working with SWF the last page of your flow process (i.e: 5/5 ) should let you finish the process or generate a pdf report, you can choose one of them. If you choose the report, it should open a pdf report (Adobe Reader would be executed) but not disposing the last jsp page of the flow process, to let you finish the flow. The other case is when you arrive to the last jsp page and you don't want the report yet, then you only finish the flow process.
- If in the flow process mentioned above you didn't generate the report and terminated the process, but after of some time now it is need it, you would call some option in the web menu and request the desired report (maybe provide some request parameter) - for this case it is enough to use the Spring Web MVC. SWF wouldn't be logical here
Now you should have clear that SWF and Spring Web MVC need call the same Service/BO and retrieve the desired report.
Before to start, the frameworks and other tools used (no all are really necessary)
- Spring 2.5.0
- Spring Web Flow 1.0.5
- JasperReports 2.0.3
- Eclipse 3.4
- Tomcat 5.5.25
- TomcatPlugin 3.2.1
- Spring IDE 2.1.0
This tutorial assumes basic-medium level about Spring and its sub-projects