Spring3+Hibernate3+FusionChartsXT for reporting

Hello all, from past few days i was working on some reports and dashboards so the requirement is to call some spring services, which return the data in the form of JSON. my responsibility is to receive the JSON data and feed it to correct chart and render it so im here to share my experience in the form of small example.

please create a database as shown below:

DROP TABLE IF EXISTS `test`.`maps`;
CREATE TABLE  `test`.`maps` (
  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `STATE_NAME` varchar(100) NOT NULL,
  `STATE_CODE` varchar(10) NOT NULL,
  `POPULATION` varchar(5) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

please download the fusionchartsXT latest(trail) version from here, after you download, create a mavanized project in eclipse.
In the pom.xml please add the below content.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.spark.spring.fusioncharts</groupId>
	<artifactId>SpringFusionCharts</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>SpringFusionCharts</name>
	<description>SpringFusionCharts</description>

	<properties>
		<jdk.version>1.6</jdk.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>3.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>3.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>3.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>3.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>3.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>3.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-oxm</artifactId>
			<version>3.2.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.15</version>
			<exclusions>
				<exclusion>
					<groupId>com.sun.jmx</groupId>
					<artifactId>jmxri</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jdmk</groupId>
					<artifactId>jmxtools</artifactId>
				</exclusion>
				<exclusion>
					<groupId>javax.jms</groupId>
					<artifactId>jms</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
		</dependency>
		<dependency>
			<groupId>net.sf.ezmorph</groupId>
			<artifactId>ezmorph</artifactId>
			<version>1.0.6</version>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.1</version>
		</dependency>
		<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>3.2.1</version>
		</dependency>
		<dependency>
			<groupId>commons-beanutils</groupId>
			<artifactId>commons-beanutils</artifactId>
			<version>1.8.3</version>
		</dependency>
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
		</dependency>
		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
			<classifier>jdk15</classifier>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate</artifactId>
			<version>3.5.4-Final</version>
			<type>pom</type>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-annotations</artifactId>
			<version>3.5.4-Final</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.15</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.5.6</version>
		</dependency>
		<dependency>
			<groupId>javassist</groupId>
			<artifactId>javassist</artifactId>
			<version>3.12.1.GA</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>SpringFusionCharts</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-eclipse-plugin</artifactId>
				<version>2.9</version>
				<configuration>
					<downloadSources>true</downloadSources>
					<downloadJavadocs>false</downloadJavadocs>
					<wtpversion>2.0</wtpversion>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>${jdk.version}</source>
					<target>${jdk.version}</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

once this step is done all your dependencies(jar files) are managed my maven.now go and create “WEB-INF,charts,javascript” folders in src/main/webapp. In WEB-INF please put web.xml as follows.

<web-app id="WebApp_ID" version="2.4"
	xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<listener>
		<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
	</listener>
	
	<servlet>
		<servlet-name>spring</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring-context.xml</param-value>
		</init-param>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>spring</servlet-name>
		<url-pattern>/spring/*</url-pattern>
	</servlet-mapping>
	
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

After this step please extract the downloaded FusionChartsXT.zip in desired location, from that navigate to the folder charts, copy all the swf files and put them in the charts folder of your eclipse(src/main/webapp/charts)
now again from the FusionChartsXT home copy “FusionCharts.js,Jquery.min.js” and put them in javascript folder of your eclipse.
Now it’s time to code logic.Lets integrate Spring and Hibernate to query the database and here i transform the
result from database to JSON format, and return that to JSP.

Note: please create separate packages for interfaces and their implementations as it gives the project a clear separation between layers(good practice)

Let us see the ServiceLayer:

package com.spark.spring.fusioncharts.service;

import java.util.List;

import com.spark.spring.fusioncharts.model.Maps;

public interface GetStatasticsDataService {

	public List<Maps> getPopulationByCountry();
}

/**
 * 
 */
package com.spark.spring.fusioncharts.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.spark.spring.fusioncharts.dao.GetStatasticsData;
import com.spark.spring.fusioncharts.model.Maps;
import com.spark.spring.fusioncharts.service.GetStatasticsDataService;

/**
 * @author Sony
 *
 */
@Service(value="GetStatasticsDataServiceImpl")
public class GetStatasticsDataServiceImpl implements GetStatasticsDataService {

	@Autowired
	GetStatasticsData getStatasticsData;
	
	/* (non-Javadoc)
	 * @see com.spark.spring.fusioncharts.service.GetStatasticsDataService#getOilConsumebyCountry()
	 */
	@Override
	public List<Maps> getPopulationByCountry() {
		
		return getStatasticsData.getOilConsumebyCountry();
	}

}

Let us see the DAOLayer:

/**
 * 
 */
package com.spark.spring.fusioncharts.dao;

import java.util.List;

import com.spark.spring.fusioncharts.model.Maps;

/**
 * @author Sony
 *
 */
public interface GetStatasticsData {

	public List<Maps> getPopulationByCountry();
}

/**
 * 
 */
package com.spark.spring.fusioncharts.dao.impl;

import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import com.spark.spring.fusioncharts.dao.GetStatasticsData;
import com.spark.spring.fusioncharts.model.Maps;

/**
 * @author Sony
 *
 */
@Repository(value="GetStatasticsDataImpl")
public class GetStatasticsDataImpl extends HibernateDaoSupport implements GetStatasticsData{

	@Autowired
	public void init(SessionFactory factory) {
	    setSessionFactory(factory);
	}
	
	@Override
	public List<Maps> getPopulationByCountry() {
		
		List<Maps> mapsList = getHibernateTemplate().loadAll(Maps.class);
		return mapsList;
	}

}

Let us see the ModelLayer:

package com.spark.spring.fusioncharts.model;

import java.io.Serializable;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * <p>Pojo mapping TABLE maps</p>
 * <p></p>
 *
 * <p>Generated at Sun Jun 30 20:56:48 IST 2013</p>
 * @author Salto-db Generator v1.0.16 / EJB3
 * 
 */
@Entity
@Table(name = "maps")
@SuppressWarnings("serial")
public class Maps implements Serializable {

	/**
	 * Attribute id.
	 */
	private Integer id;
	
	/**
	 * Attribute stateName.
	 */
	private String stateName;
	
	/**
	 * Attribute stateCode.
	 */
	private String stateCode;
	
	/**
	 * Attribute population.
	 */
	private String population;
	
	
	/**
	 * <p> 
	 * </p>
	 * @return id
	 */
	@Basic
	@Id
	@GeneratedValue
	@Column(name = "ID")
		public Integer getId() {
		return id;
	}

	/**
	 * @param id new value for id 
	 */
	public void setId(Integer id) {
		this.id = id;
	}
	
	/**
	 * <p> 
	 * </p>
	 * @return stateName
	 */
	@Basic
	@Column(name = "STATE_NAME", length = 100)
		public String getStateName() {
		return stateName;
	}

	/**
	 * @param stateName new value for stateName 
	 */
	public void setStateName(String stateName) {
		this.stateName = stateName;
	}
	
	/**
	 * <p> 
	 * </p>
	 * @return stateCode
	 */
	@Basic
	@Column(name = "STATE_CODE", length = 10)
		public String getStateCode() {
		return stateCode;
	}

	/**
	 * @param stateCode new value for stateCode 
	 */
	public void setStateCode(String stateCode) {
		this.stateCode = stateCode;
	}
	
	/**
	 * <p> 
	 * </p>
	 * @return population
	 */
	@Basic
	@Column(name = "POPULATION", length = 5)
		public String getPopulation() {
		return population;
	}

	/**
	 * @param population new value for population 
	 */
	public void setPopulation(String population) {
		this.population = population;
	}
}

Let us see the ControllerLayer:

/**
 * 
 */
package com.spark.spring.fusioncharts.controller;

import java.util.List;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.spark.spring.fusioncharts.model.Maps;
import com.spark.spring.fusioncharts.service.GetStatasticsDataService;

/**
 * @author Sony
 *
 */
@Controller
public class ChartsController {
	
	@Autowired
	GetStatasticsDataService getStatasticsDataService;

	@RequestMapping(value="/charts")
	public @ResponseBody String getChartsDashboard(){
		List<Maps> oilconsumebycountries = getStatasticsDataService.getPopulationByCountry();
		JSONArray jsonArray = (JSONArray)JSONSerializer.toJSON(oilconsumebycountries);
		return jsonArray.toString();
	}
	
	

}

Now let’s start looking at the resource files inorder to configure the application.

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
            http://www.springframework.org/schema/jdbc
            http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd
            http://www.springframework.org/schema/mvc 
            http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

	<context:component-scan base-package="com.spark.spring.fusioncharts"></context:component-scan>
	<context:annotation-config></context:annotation-config>
	<mvc:annotation-driven></mvc:annotation-driven>

	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost:3306/test" />
		<property name="username" value="root" />
		<property name="password" value="root" />
	</bean>

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation">
			<value>classpath:hibernate.cfg.xml</value>
		</property>
		<property name="configurationClass">
			<value>org.hibernate.cfg.AnnotationConfiguration</value>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
			</props>
		</property>
	</bean>
</beans>

spring-context

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

	<!-- Enables the Spring MVC @Controller programming Model -->
	<context:component-scan base-package="com.spark.spring.fusioncharts"></context:component-scan>
	<context:annotation-config></context:annotation-config>
	<annotation-driven></annotation-driven>

	<beans:bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix">
			<beans:value>/WEB-INF/pages/</beans:value>
		</beans:property>
		<beans:property name="suffix">
			<beans:value>.jsp</beans:value>
		</beans:property>

	</beans:bean>

</beans:beans>

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <mapping class="com.spark.spring.fusioncharts.model.Maps" />
    </session-factory>
</hibernate-configuration>

log4j.properties

# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=D\:\\logger.log
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
 
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
 
# Root logger option
#log4j.rootLogger=debug, file, stdout
log4j.rootLogger=info, ROOT, file
#log4j.rootLogger=fatal, file, stdout
#log4j.rootLogger=ERROR, file, stdout

Now lets code the view(JSP) part of our project.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>spring3.2+Fusion Charts</title>
<script type="text/javascript" src="javascript/jquery.min.js"></script>
<script type="text/javascript" src="javascript/FusionCharts.js"></script>
<script type="text/javascript" src="javascript/Mycharts.js"></script>
</head>
<body>
	<div style="width: 1300px;">
		<div id="piechartContainer" style="float: left; width: 600px;">FusionCharts XT will load here!</div>
		<div id="barchartContainer" style="float: right; width: 600px;">FusionCharts XT will load here!</div>
		<br style="clear: left;" />
	</div>
	
	<div style="width: 1300px;">
		<div id="pyramidchartContainer" style="float: left; width: 600px;">FusionCharts XT will load here!</div>
		<div id="linechartContainer" style="float: right; width: 600px;">FusionCharts XT will load here!</div>
		<br style="clear: left;" />
	</div>

</body>
</html>

inorder to render the charts in our dashboard please write your own javascript code as follows
Mycharts.js

$(document).ready(
		function() {
			$.ajax({
				url : "http://localhost:8080/SpringMVC/spring/charts",
				dataType : "json",
				success : function(data) {
					
					var dataObjectArray = new Array();
					
					var myPieChart = new FusionCharts("Charts/Pie3D.swf",
							"myChartId", "750", "450", "0");
					var myBarChart = new FusionCharts("Charts/Column3D.swf",
							"myChartId2", "750", "450", "0");
					var myLineChart = new FusionCharts("Charts/Line.swf",
							"myChartId3", "750", "450", "0");
					var myPyramidChart = new FusionCharts("Charts/Pyramid.swf",
							"myChartId3", "750", "450", "0");

					var dataStr = {
						'chart' : {
							'caption' : 'population per state',
							'xAxisName' : 'states',
							'yAxisName' : 'population',
							'numberPrefix' : ''
						},
						'data' : [ ]
					};

					$.each(data, function(key, value) {
						//alert(value.population + "" + value.stateName);
						var dataObject = {
								label:'',
								value:''
							}
						dataObject.label = value.stateName;
						dataObject.value = value.population;
						dataObjectArray.push(dataObject);
					});
					
					dataStr.data = dataObjectArray;
					myPieChart.setJSONData(dataStr);
					myPieChart.render("piechartContainer");

					myBarChart.setJSONData(dataStr);
					myBarChart.render("barchartContainer");

					myLineChart.setJSONData(dataStr);
					myLineChart.render("linechartContainer");

					myPyramidChart.setJSONData(dataStr);
					myPyramidChart.render("pyramidchartContainer");

				},
				error : function(data) {

				}
			});
		});

once done please run the poject and in browser it shows as below. report of same data with four different charts.
FusionChartsReport

Happy Coding:)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s