Tuesday, January 31, 2012

Spring MVC 3.1 and JasperReports: Using iReport and AJAX (Part 1)

In this tutorial, we will study how to generate reports from a Spring MVC 3.1 application using JasperReports. We will use jQuery and jqGrid to provide AJAX support and an interactive table. To design the report, we will use iReport, an open source report designer for JasperReports. On the data layer, we'll utilize MySQL, Hibernate, and Spring Data JPA.


Dependencies

  • Spring core 3.1.0.RELEASE
  • Spring Data JPA 1.1.0.M1
  • jQuery 1.6.4
  • jqGrid 4.3.1
  • Jasper Reports 4.5.0
  • See pom.xml for details

Github

To access the source code, please visit the project's Github repository (click here)

Functional Specs

Before we start, let's define our application's specs as follows:
  • Display reports in an interactive table
  • Downloadable reports in PDF and Excel formats
  • Use AJAX to avoid page refresh
  • Users have roles. They are either admin or regular (default)
  • A username is assumed to be unique

Here's our Use Case diagram:
[User]-(View)
[User]-(Download Pdf) 
[User]-(Download Excel)

Database

Our database contains two tables: user and role tables.


user and role table design

User table

The user table contains personal information of each user. Notice the password values are hashed using Md5.

user table

Role table

The role table contains role values of each user. We define a role value of 1 as an admin, while a role value of 2 as a regular user.

role table

Screenshots

Before we start with the actual development, let's preview how our application will look like. This is also a good way to clarify further the application's specs.

Entry page
The entry page is the primary page that users will see. It contains an interactive table where users can view and download records.
Entry page

Pdf document
This is the downloadable Pdf document whenever the user clicks on the Pdf button.
Report in Pdf format as previewed from Chrome

Excel document
This is the downloadable Excel document whenever the user clicks on the Excel button. When using Excel format, the document's appearance varies depending on the application, i.e Microsoft Excel, Google Docs, Open Office.
Report in Excel format as previewed from Google Docs

Progress dialog
When a user clicks on any of the download buttons (Pdf or Excel), a progress dialog will appear and disappears once the download starts.
Progress alert


Next

In the next section, we will discuss the project's structure and write the Java classes. Click here to proceed.
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring MVC 3.1 and JasperReports: Using iReport and AJAX (Part 1) ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

Spring MVC 3.1 and JasperReports: Using iReport and AJAX (Part 2)

Review

In the previous section, we have laid down the functional specs of the application. In this section, we will discuss the project's structure and write the Java classes in layers.


Project Structure

Our application is a Maven project and therefore follows Maven structure. As we create the classes, we've organized them in logical layers: domain, repository, service, and controller.

Here's a preview of our project's structure:

The Layers

Domain

This layer contains two domain classes, User and Role. They represent our database tables, user and role respectively. Because we're developing a JPA-based repository, both classes must be annotated with JPA annotations.




Data Transfer Object (DTO)

This layer contains four DTO classes:
  • UserDto is a POJO for mapping User objects to and from the presentation layer
  • StatusResponse is a POJO for sending boolean responses to the presentation layer
  • JqgridResponse is a container for UserDto objects for sending records to the jqGrid table. It contains information regarding the number of rows, current page, and total pages.
  • JasperDto is a POJO for mapping User objects into something that Jasper can process easily (This is used for reporting purposes only.)

Note: We won't display the contents of UserDto, StatusReponse, and JqgridResponse here since we've already discussed that on a different tutorial (see Spring MVC 3.1, jqGrid, and Spring Data JPA Integration Guide (Part 2))



Controller

This layer contains two controllers, MediatorController and UserController.
  • MediatorController is responsible for redirecting requests from the root path to the Users page
  • UserController is responsible for handling user related requests, including download requests




Let's describe the methods available from UserController:
  • The records() method returns a list of UserDto objects as JSON strings. This will be displayed on the presentation layer as an interactive grid of data with the help of jqGrid plugin.
  • checkDownloadProgress() method is used to check if a download token is present or not. See Download Token Algorithm below
  • getDownloadToken() method is used to retrieve a download token. See Download Token Algorithm below
  • download() method performs the actual report download by delegating it to the DownloadService.

Download Token Algorithm
(Inspired by Detect when browser receives file download)

This is basically a fancy way of adding a progress box in an AJAX environment, so that we can display the status of a download requests. In a typical AJAX requests, the call is perform asynchronously, and the user does not know if the requests is being processed unless we provide a progress report. Unfortunately, you can't use AJAX directly for file downloads.

However, you can provide an illusion of a progress report through the Download Token Algorithm:
  1. User clicks on download button. A progress box appears.
  2. Download button performs an AJAX requests to retrieve a download token
  3. Once a download token has been received, a call to the actual download URL is performed. (This is not an AJAX requests)
  4. Periodically perform an AJAX requests to check if the download token retrieved earlier still exists. If not, the download has started.
  5. If the download token does not exists anymore, close the progress box.

Repository

This layer contains a single interface, UserRepository. This is our data access object (DAO). With the help of Spring Data JPA, Spring will automatically provide the actual implementation.

What is Spring Data JPA?

Spring JPA is part of the umbrella Spring Data project that makes it easy to easily implement JPA based repositories.

Implementing a data access layer of an application has been cumbersome for quite a while. Too much boilerplate code has to be written to execute simple queries as well as perform pagination, and auditing. Spring JPA aims to significantly improve the implementation of data access layers by reducing the effort to the amount that's actually needed. As a developer you write your repository interfaces, including custom finder methods, and Spring will provide the implementation automatically.

Source: http://www.springsource.org/spring-data/jpa



Service

This layer contains the following services:
  • TokenService: This is responsible for providing and managing download tokens. See the Download Token Algorithm above.
  • JasperDatasourceService: Wraps a list of objects into a JRBeanCollectionDataSource. This is the datasource for our Jasper reports.
  • ExporterService: This is responsible for exporting a Jasper report into different formats, such as Pdf and Excel.
  • DownloadService: This is responsible for the actual download requests and writing of reports to the output stream






The DownloadService is the heart of the download process. The algorithm is as follows:
  1. Add report parameters
  2. Retrieve template
  3. Convert template to JasperDesign
  4. Compile design to JasperReport
  5. Create the JasperPrint object
  6. Create an output byte stream where data will be written
  7. Export report
  8. Write to reponse stream

Utilities

  • JqgridFilter is a Java representation of a jqGrid filter
  • JqgridObjectMapper is used to convert a jqGrid filter to a JqgridFilter object
  • UserMapper is used to map User objects to UserDto objects
  • TraceInterceptor is an AOP-based utility class to help us debug our application. This is a subclass of CustomizableTraceInterceptor. See Spring Data JPA FAQ

Note: We won't display the contents of JqgridFilter, JqgridObjectMapper, UserMapper, and TraceInterceptor here since we've already discussed them on a different tutorial. See Spring Data JPA FAQ

Next

In the next section, we will create the Jasper report layout and design it using iReport. Click here to proceed.
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring MVC 3.1 and JasperReports: Using iReport and AJAX (Part 2) ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

Spring MVC 3.1 and JasperReports: Using iReport and AJAX (Part 3)

Review

In the previous section, we have created the Java classes and discussed the download process. In this section, we will focus on the Jasper layout and study how to design one using iReport.


Jasper Layout

The Jasper report layout is basically an XML document. You can create it through any text editor (if you know the syntax) or you can use a WYSWYG-editor. We choose the latter because it's easier.

What is iReport?

iReport is the free, open source report designer for JasperReports. Create very sophisticated layouts containing charts, images, subreports, crosstabs and much more. Access your data through JDBC, TableModels, JavaBeans, XML, Hibernate, CSV, and custom sources. Then publish your reports as PDF, RTF, XML, XLS, CSV, HTML, XHTML, text, DOCX, or OpenOffice.

Source: iReport

Final Design

Before we proceed, let's preview the final design:

Admittedly, this isn't the best looking design, but it's good enough for our purpose.


Project Structure

Below is a screenshot of the project's structure:

Installation

To start using iReport, we must first download and install one. Below are the instructions for installing and running iReport in Windows (Ubuntu will follow later):

Windows
1. Open a browser and visit the iReport site at http://jasperforge.org/projects/ireport

2. Click on the download button. It will ask you to register first, but you can skip it.
You should see the following options:

3. Choose the Windows installer.

4. Once the download is finished, install it.

Designing

We'll now start designing our report

1. Run iReport

2. Go to File and click New. You should see the following window

3. Select Report and click on the Coffee Landscape template. You will be asked to save the project.

4. Click Finish when done. You should see the following window:

Now, it's time to design the report.

5. On the left side, under the Report Inspector, you should see a list of items. Expand the Fields section. You should see the following items: id, username, firstName, lastName, role.

Click on any of the fields and change their properties as indicated below (the Properties panel is located on the right-side):






6. On the left side, under the Report Inspector, expand the Detail section. You should see the following items: $F{id}, $F{username}, $F{firstName}, $F{lastName}, $F{role}. These are value placeholders.

Click on any of the fields and change their properties as indicated below. Make sure to edit the Detail section itself and the bounding box as well.









7. On the left side, under the Report Inspector, expand the Column Header section. You should see the following items: ID, Username, First Name, LastName, Role. These are the labels for each fields accordingly.

Click on any of the fields and change their properties as indicated below. Make sure to edit the Detail section itself and the bounding box as well.






8. Now, let's update the title. Change it from Coffee Title to User Records


9. Update the subtitle as well. Change it from Coffee SubTitle to A Summary:

10. We're done with the design. Now, let's update the report's programming language (This is critical!). Click outside the report layout. Then on the Properties panel, scroll down and look for the Language property. Change it from Groovy to Java!

Before
After
11. Save the file, and we're done.

Transferring the Layout

After creating the design, we should now copy and save it to the classpath directory of our Spring project.

Here are the steps:

1. Open the folder or directory where you saved your report. Notice that the images are saved along with the report.
  • coffee.jpg: an image
  • coffee_stain.jpg: an image
  • users.jasper: compiled report (we don't need this one)
  • users.jrxml: the report layout (this is important)

2. Copy all the files except the users.jasper and paste it under the src/main/resources folder of your Spring project.

That's it! We've completed the transfer.

Next

In the next section, we will focus on the presentation layer, in particular the tabular display of our records using jqGrid and HTML. Click here to proceed.
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring MVC 3.1 and JasperReports: Using iReport and AJAX (Part 3) ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

Spring MVC 3.1 and JasperReports: Using iReport and AJAX (Part 4)

Review

In the previous section, we have created the Jasper report layout using iReport and learned where to place them on our Spring project. In this section, we will focus on the presentation layer and learn how to display data using HTML and jqGrid.


Presentation Layer

We will use jqGrid to display our data in an interactive table and jQuery to provide AJAX support.

What is jQuery?

jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript.

Source: http://jquery.com/

What is jqGrid?

jqGrid is an Ajax-enabled JavaScript control that provides solutions for representing and manipulating tabular data on the web. Since the grid is a client-side solution loading data dynamically through Ajax callbacks, it can be integrated with any server-side technology, including PHP, ASP, Java Servlets, JSP, ColdFusion, and Perl.

Source: http://www.trirand.com/jqgridwiki/doku.php

Preview

We only have a single HTML file (users.jsp, a JSP to be exact) to perform all actions. This page contains our jqGrid table and buttons for downloading reports in Pdf and Excel format.

Entry page

Source

At first glance, when you look at the JavaScript code, it is somewhat intimidating, but once you've familiarized with the jqGrid syntax, you'll find that it's actually simple. If you aren't familiary with jqGrid, please visit the jqGrid Official Wiki


You might be asking: "What's that humongous lines of jibberish code?" If you'd been following my blog, you would notice that I have tackled jqGrid a couple of times from my previous tutorials. If my explanation in this tutorial isn't enough, please see the following tutorials for an alternative perspective:


An In-depth Look

If we partition this JSP page, you will notice the following sections:
  • URL imports
  • JavaScript and CSS imports
  • jqGrid initialization
  • JavaScript functions: downloadXls(), downloadPdf(), download()

    Pay attention to the download() function's algorithm:

    1. Retrieve a download token via AJAX.
    2. Store the token.
    3. Show download progress dialog box.
    4. Start actual download.
    5. Do a periodic AJAX call to verify if token still exists. If not, hide download progress box.
  • HTML table

Notice how we've separated the HTML markup from the JavaScript code. We could, of course, move that one huge JavaScript code in an external js file, and make the HTML look somewhat smaller. But I'll leave that exercise to my readers.

Next

In the next section, we will focus on the configuration files for enabling Spring MVC. Click here to proceed.
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring MVC 3.1 and JasperReports: Using iReport and AJAX (Part 4) ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

Spring MVC 3.1 and JasperReports: Using iReport and AJAX (Part 6)

Review

We have just completed our application! In the previous sections, we have discussed the functional specs, created the Java classes, designed the Jasper reporty layout, declared the configuration files, and wrote the JSP files. In this section, we will build and run the application using Maven, and show how to import the project in Eclipse.


Running the Application

Access the source code

To download the source code, please visit the project's Github repository (click here)

Preparing the data source

  1. Run MySQL (install one if you don't have one yet)
  2. Create a new database:
    spring_jasper_tutorial
  3. Import the following file which is included in the source code under the src/main/resources folder:
    spring_jasper_tutorial.sql

Building with Maven

  1. Ensure Maven is installed
  2. Open a command window (Windows) or a terminal (Linux/Mac)
  3. Run the following command:
    mvn tomcat:run
  4. You should see the following output:
    [INFO] Scanning for projects...
    [INFO] Searching repository for plugin with prefix: 'tomcat'.
    [INFO] artifact org.codehaus.mojo:tomcat-maven-plugin: checking for updates from central
    [INFO] artifact org.codehaus.mojo:tomcat-maven-plugin: checking for updates from snapshots
    [INFO] ------------------------------------------
    [INFO] Building spring-jasper-tutorial Maven Webapp
    [INFO]    task-segment: [tomcat:run]
    [INFO] ------------------------------------------
    [INFO] Preparing tomcat:run
    [INFO] [apt:process {execution: default}]
    [INFO] [resources:resources {execution: default-resources}]
    [INFO] [tomcat:run {execution: default-cli}]
    [INFO] Running war on http://localhost:8080/spring-jasper-tutorial
    Jan 31, 2012 10:39:22 PM org.apache.catalina.startup.Embedded start
    INFO: Starting tomcat server
    Jan 31, 2012 10:39:23 PM org.apache.catalina.core.StandardEngine start
    INFO: Starting Servlet Engine: Apache Tomcat/6.0.29
    Jan 31, 2012 10:39:23 PM org.apache.catalina.core.ApplicationContext log
    INFO: Initializing Spring root WebApplicationContext
    Jan 31, 2012 10:39:29 PM org.apache.coyote.http11.Http11Protocol init
    INFO: Initializing Coyote HTTP/1.1 on http-8080
    
  5. Note: If the project will not build due to missing repositories, please enable the repositories section in the pom.xml!

Access the Entry page

  1. Follow the steps with Building with Maven
  2. Open a browser
  3. Enter the following URL (8080 is the default port for Tomcat):
    http://localhost:8080/spring-jasper-tutorial/

Import the project in Eclipse

  1. Ensure Maven is installed
  2. Open a command window (Windows) or a terminal (Linux/Mac)
  3. Run the following command:
    mvn eclipse:eclipse -Dwtpversion=2.0
  4. You should see the following output:
    [INFO] Scanning for projects...
    [INFO] Searching repository for plugin with prefix: 'eclipse'.
    [INFO] org.apache.maven.plugins: checking for updates from central
    [INFO] org.apache.maven.plugins: checking for updates from snapshots
    [INFO] org.codehaus.mojo: checking for updates from central
    [INFO] org.codehaus.mojo: checking for updates from snapshots
    [INFO] artifact org.apache.maven.plugins:maven-eclipse-plugin: checking for updates from central
    [INFO] artifact org.apache.maven.plugins:maven-eclipse-plugin: checking for updates from snapshots
    [INFO] -----------------------------------------
    [INFO] Building spring-jasper-tutorial Maven Webapp
    [INFO]    task-segment: [eclipse:eclipse]
    [INFO] -----------------------------------------
    [INFO] Preparing eclipse:eclipse
    [INFO] No goals needed for project - skipping
    [INFO] [eclipse:eclipse {execution: default-cli}]
    [INFO] Adding support for WTP version 2.0.
    [INFO] -----------------------------------------
    [INFO] BUILD SUCCESSFUL
    [INFO] -----------------------------------------
    
    This command will add the following files to your project:
    .classpath
    .project
    .settings
    target
    You may have to enable "show hidden files" in your file explorer to view them
  5. Open Eclipse and import the project

Conclusion

That's it! We've have successfully completed our Spring MVC 3.1 web application. We've learned how to add downloadable reports with JasperReports in an AJAX application, and use iReport to design the layout.

I hope you've enjoyed this tutorial. Don't forget to check my other tutorials at the Tutorials section.

Revision History


Revision Date Description
1 Jan 31 2012 Uploaded tutorial and Github repository

StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring MVC 3.1 and JasperReports: Using iReport and AJAX (Part 6) ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

Spring MVC 3.1 and JasperReports: Using iReport and AJAX (Part 5)

Review

In the previous section, we have focused on the presentation layer and discussed jqGrid. In this section, we will focus on the configuration files, in particular the XML files.


Configuration

Database properties

We'll use MySQL as our application's database. However, it's also possible to use a different database provider. Therefore, to make switching database simpler, we've externalized our database configuration within a properties file.


Application Context

Below is a typical application context file for enabling Spring MVC support.


Spring Data

In conjuction with the spring.properties file, we have to declare the actual datasource. Notice we're using JPA and Spring Data JPA support.


Next

In the next section, we will build and run the application using Maven, and show how to import the project in Eclipse. Click here to proceed.
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring MVC 3.1 and JasperReports: Using iReport and AJAX (Part 5) ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share