Spring Data Rest + AngularJS + MongoDB

Hello everybody, this time i took little long time to post an article here. Here i came up with a very powerful integration pack called “Integration of Spring data rest with AngularJS and MongoDB”. Now a days this combination is best suited for SPA – “Single Page Application” with light weight back end support with mongodb. Now we will have a Jump start into the tutorial. this tutorial will assume the prior basic knowledge of

  • Java8
  • Spring & Spring Data Rest
  • MongoDB

the project structure looks as below.
SpringAngularJSProj

Before proceeding with the Spring integration with angularjs and mongodb, please install mongodb and start the mongodb server. if everything goes well server startup should look as below.
mongodb_server_start

Now install any GUI client for mongodb for easy access, we can even access mongodb with out client but this is for better user experience. I personally use “Robomongo” and once you connect Robomongo to MongoDB server that will look as below.
robomongo

Once everything is ready and inplace, let us start with writing the code. I have used Maven to manage the dependencies and hence the pom.xml looks as below.

<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.ng.spring</groupId>
	<artifactId>AngularSpring</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>AngularSpring</name>
	<description>AngularSpring</description>

	<properties>
		<spring-version>4.1.2.RELEASE</spring-version>
		<jdk-version>1.8</jdk-version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-rest-core</artifactId>
			<version>2.3.0.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-mongodb</artifactId>
			<version>1.5.2.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-rest-webmvc</artifactId>
			<version>2.3.0.RELEASE</version>
		</dependency>

		<!-- mongodb java driver -->
		<dependency>
			<groupId>org.mongodb</groupId>
			<artifactId>mongo-java-driver</artifactId>
			<version>2.11.0</version>
		</dependency>
		
		<!-- Servlet 3.x api -->
		 <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        
	</dependencies>

	<build>
		<finalName>AngularSpring</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.4</version>
				<configuration>
					<warSourceDirectory>src/main/webapp</warSourceDirectory>
					<warName>AngularSpring</warName>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Once the dependencies are downloaded let us start with the configuration. In this tutorial i am moving with NoXml style of configuration.
ApplicationConfig.java

/**
 * 
 */
package com.spark.ng.spring.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

import com.mongodb.MongoClient;

/**
 * @author Mantha Pavan Kumar
 *
 */
@Configuration
@EnableWebMvc
@ComponentScan(basePackages={"com.spark.ng.spring"})
@EnableMongoRepositories(basePackages={"com.spark.ng.spring.data.repository"})
@Import(RepositoryRestMvcConfiguration.class)
public class ApplicationConfig {
	
	public @Bean
    MongoDbFactory mongoDbFactory() throws Exception {
		MongoClient mongoClient = new MongoClient("localhost",27017);
        return new SimpleMongoDbFactory(mongoClient, "Customer");
    }

    public @Bean
    MongoTemplate mongoTemplate() throws Exception {
        MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
        return mongoTemplate;
    }
    
	@Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".html");
 
        return viewResolver;
    }
}

WebApplicationConfig.java

/**
 * 
 */
package com.spark.ng.spring.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

/**
 * @author Mantha Pavan Kumar
 *
 */
public class WebApplicationConfig implements WebApplicationInitializer{

	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {
		
		AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext();
		annotationConfigWebApplicationContext.register(ApplicationConfig.class);
		annotationConfigWebApplicationContext.setServletContext(servletContext);
		
		ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(annotationConfigWebApplicationContext));
		servlet.setLoadOnStartup(1);
		servlet.addMapping("/rest/*");
	}

}

With the above two files we are done with the configuration part. Let us talk about ApplicationConfig.java a little more in deep. At the top of the class please take a close look, i have annotated the class with “@EnableWebMvc”, which will enable all “@Component” based class and scans them when the application is loaded by the web container. The annotation “@EnableWebMvc” is equivalent to “”. Moving little forward “@ComponentScan” will scan all the @Component based classes. Now comes the “@EnableMongoRepositories” which will load all the repositories. Finally we have imported a core class from the Spring API called “RepositoryRestMvcConfiguration” this is the class responsible for converting the domain objects back and forth to JSON format and acts as a communication bridge between clint(browser) & backend. In this class we have innitialised two beans called “MongoDBFactory” & “MongoTemplate” since if we have any operation to do apart from Repository implementation then we can use of “MongoTemplate” object to fulfill that.

Let us have a look at the domain object Customer.java

/**
 * 
 */
package com.spark.ng.spring.domain.objects;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;


/**
 * @author PavanKumar Mantha
 *
 */
@Document(collection="customer")
public class Customer {

	@Id
	@Field
	private String id;
	@Field
	private String customerId;
	@Field
	private String firstName;
	@Field
	private String lastName;
	@Field
	private String contactAddr;
	@Field
	private String mobileNumber;
	

	/**
	 * @return the customerId
	 */
	public String getCustomerId() {
		return customerId;
	}

	/**
	 * @param customerId
	 *            the customerId to set
	 */
	public void setCustomerId(String customerId) {
		this.customerId = customerId;
	}

	/**
	 * @return the firstName
	 */
	public String getFirstName() {
		return firstName;
	}

	/**
	 * @param firstName
	 *            the firstName to set
	 */
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	/**
	 * @return the lastName
	 */
	public String getLastName() {
		return lastName;
	}

	/**
	 * @param lastName
	 *            the lastName to set
	 */
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	/**
	 * @return the contactAddr
	 */
	public String getContactAddr() {
		return contactAddr;
	}

	/**
	 * @param contactAddr
	 *            the contactAddr to set
	 */
	public void setContactAddr(String contactAddr) {
		this.contactAddr = contactAddr;
	}

	/**
	 * @return the mobileNumber
	 */
	public String getMobileNumber() {
		return mobileNumber;
	}

	/**
	 * @param mobileNumber
	 *            the mobileNumber to set
	 */
	public void setMobileNumber(String mobileNumber) {
		this.mobileNumber = mobileNumber;
	}

}

A generic Response object with which we can send messages back to browser.

/**
 * 
 */
package com.spark.ng.spring.domain.objects;

/**
 * @author Sony
 *
 */
public class ResponseObject {

	private String message;

	/**
	 * @return the message
	 */
	public String getMessage() {
		return message;
	}

	/**
	 * @param message
	 *            the message to set
	 */
	public void setMessage(String message) {
		this.message = message;
	}

}

The class “ApplicationRepositoryUtil.java will get us all the objects that are required using the @Autowired annotation.

/**
 * 
 */
package com.spark.ng.spring.data.repository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

/**
 * @author Sony
 *
 */
@Service
public class ApplicationRepositoryUtil {

	@Autowired
	private MongoTemplate mongoTemplate;
	@Autowired
	private CustomerRepository customerRepository;

	/**
	 * @return the mongoTemplate
	 */
	public MongoTemplate getMongoTemplate() {
		return mongoTemplate;
	}

	/**
	 * @return the customerRepository
	 */
	public CustomerRepository getCustomerRepository() {
		return customerRepository;
	}

}

Here comes the exact repository that we were talking from little while. Please observe the repository carefully. Its an interface extending one more interface called “MongoRepository”.The goal of Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.The central interface in Spring Data repository abstraction is Repository (probably not that much of a surprise). It takes the domain class to manage as well as the id type of the domain class as type arguments. This interface acts primarily as a marker interface to capture the types to work with and to help you to discover interfaces that extend this one. The CrudRepository provides sophisticated CRUD functionality for the entity class that is being managed. MongoRepository extends the basic CrudRepository.

/**
 * 
 */
package com.spark.ng.spring.data.repository;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

import com.spark.ng.spring.domain.objects.Customer;

/**
 * @author Sony
 *
 */
@RepositoryRestResource(collectionResourceRel="customer",path="customer")
public interface CustomerRepository extends MongoRepository<Customer, Integer> {

}

Here is a simple controller that will receive the requests from clients and delegates them to appropriate layers.

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

import java.util.function.Supplier;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.spark.ng.spring.data.repository.ApplicationRepositoryUtil;
import com.spark.ng.spring.domain.objects.ResponseObject;

/**
 * @author Sony
 *
 */
@RestController
@RequestMapping(value = "/app")
public class ApplicationController {

	@Autowired
	ApplicationRepositoryUtil applicationRepositoryUtil;

	@RequestMapping("/test")
	public ResponseObject handleRequest() {
		System.out
				.println("---------------------Testing method called---------------- Mongo Template :"
						+ applicationRepositoryUtil.getMongoTemplate()
						+ " Repository Object : "
						+ applicationRepositoryUtil.getCustomerRepository());
		Supplier<ResponseObject> supplier = ResponseObject::new;
		ResponseObject responseObject = supplier.get();

		responseObject.setMessage("Sample Data Object");
		return responseObject;

	}
}

Now we done with the java part and now its time for us to write the Html and java script. please download latest AngularJS library and include the “angular.min.js” inside your project, after including please write a file called “mongo.module.js” and out the following content into it.

/**
 * 
 */
var myApp = angular.module('myApp', ['controllers']);

Now write an AngularJs controller which is responsible for firing the Ajax request to the Spring and get the data in REST format. create a folder called “controllers” and create a file “controllers.js” and put the following content into it.

/**
 * 
 */

var controllersModule = angular.module('controllers', []);

controllersModule.controller('SampleController', function($scope) {
	console.log('Sample Load done !');
});

controllersModule.controller('ajaxController', function($scope, $http) {
	$http.get('/AngularSpring/rest/customer/').success(function(data) {
		console.log(data);
	});
});

Let us create an Html file “index.html” with the below content

<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="ISO-8859-1">
<title>Index Page</title>
<script type="text/javascript" src="jsLib/angular.min.js"></script>
</head>
<body>
	<div ng-controller="SampleController">Hello AngularJs</div>
	<div ng-controller="ajaxController">Hello Spring Data Rest & MongoDB</div>

</body>
<script type="text/javascript" src="mongo.module.js"></script>
<script type="text/javascript" src="controllers/controllers.js"></script>
</html>

That is it guys we are done from coding part and its time for us to build the application and deploy it to server.
Once we deploy the application into the server, please install an Add on to firefox or chrome called “RESTClient” from which we can test our repositories are working or not.
RestClient

Once you fire the request as shown in the above screen shot, we should get the response from the service as below.
REST_Response

Now try to open our page “index.html” and in firebug console we could see the same response as above which means pur angularjs is firing the request and our Spring repositories are responding to the request.

index

Happy Spring Data REst + AngularJS + MongoDB ๐Ÿ™‚
Happy Coding ๐Ÿ™‚

Spring 4 – ContentNegotiatingViewResolver Sample

Hello every one, recently in one of my project i had a requirement that i need to generate multiple views based on the request type, this has lead me to write this post. In this article i will be explaining about “ContentNegotiatingViewResolver” class.

ContentNegotiatingViewResolver class is a implementation of ViewResolver. The ContentNegotiatingViewResolver does not resolve the view by itself unlike the ViewResolver based on the request type or the Header type in fact this delegates the request to other ViewResolvers that are configured explicitly.

This view resolver uses the requested media type to select a suitable View for a request. The requested media type is determined through the configured ContentNegotiationManager. Once the requested media type has been determined, this resolver queries each delegate view resolver for a View and determines if the requested media type is compatible with the view’s content type). The most compatible view is returned.

Below is the Project Structure.
ProjStruct-1

the project pom.xml is as follows

<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.spring.ContentNegotiatingViewResolver</groupId>
	<artifactId>ContentNegotiatingViewResolver</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>ContentNegotiatingViewResolver</name>
	<description>ContentNegotiatingViewResolver</description>

	<properties>
		<springframework.version>4.0.6.RELEASE</springframework.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${springframework.version}</version>
		</dependency>

		<!-- Needed for XML View (with JAXB2) -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-oxm</artifactId>
			<version>${springframework.version}</version>
		</dependency>

		<!-- Needed for JSON View -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.4.1.3</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>2.4.1</version>
		</dependency>

		<!-- Needed for PDF View -->
		<dependency>
			<groupId>com.lowagie</groupId>
			<artifactId>itext</artifactId>
			<version>4.2.1</version>
		</dependency>

		<!-- Needed for XLS View -->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>3.10-beta2</version>
		</dependency>

		<!-- Servlet dependencies -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>javax.servlet.jsp-api</artifactId>
			<version>2.3.1</version>
		</dependency>

	</dependencies>


	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-war-plugin</artifactId>
					<version>2.4</version>
					<configuration>
						<warSourceDirectory>src/main/webapp</warSourceDirectory>
						<warName>Spring4MVCContentNegotiatingViewResolverExample</warName>
						<failOnMissingWebXml>false</failOnMissingWebXml>
					</configuration>
				</plugin>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<configuration>
						<source>1.7</source>
						<target>1.7</target>
					</configuration>
				</plugin>
				<plugin>
					<groupId>org.codehaus.mojo</groupId>
					<artifactId>tomcat-maven-plugin</artifactId>
					<version>1.0-beta-1</version>
				</plugin>
			</plugins>
		</pluginManagement>

		<finalName>Spring4MVCContentNegotiatingViewResolverExample</finalName>
	</build>
</project>

Now let us create the configuration classes as this article is based on no-xml.
AppConfig.java

package com.spark.spring.config;

import java.util.ArrayList;
import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

import com.spark.spring.domain.objects.Pizza;
import com.spark.spring.view.resolvers.ExcelViewResolver;
import com.spark.spring.view.resolvers.Jaxb2MarshallingXmlViewResolver;
import com.spark.spring.view.resolvers.JsonViewResolver;
import com.spark.spring.view.resolvers.PdfViewResolver;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.spark.spring")
public class AppConfig extends WebMvcConfigurerAdapter {

	public void configureContentNegotiation(
			ContentNegotiationConfigurer contentNegotiationConfigurer) {
		contentNegotiationConfigurer.ignoreAcceptHeader(true)
				.defaultContentType(MediaType.TEXT_HTML);
	}

	@Bean
	public ViewResolver contentNegotiationViewResolver(
			ContentNegotiationManager contentNegotiationManager) {
		ContentNegotiatingViewResolver contentNegotiatingViewResolver = new ContentNegotiatingViewResolver();
		contentNegotiatingViewResolver
				.setContentNegotiationManager(contentNegotiationManager);

		List<ViewResolver> resolvers = new ArrayList<ViewResolver>();
		resolvers.add(jaxb2MarshallingXmlViewResolver());
		resolvers.add(jsonViewResolver());
		resolvers.add(excelViewResolver());
		resolvers.add(pdfViewResolver());

		contentNegotiatingViewResolver.setViewResolvers(resolvers);
		return contentNegotiatingViewResolver;
	}

	/*
	 * Configure View resolver to provide XML output Uses JAXB2 marshaller to
	 * marshall/unmarshall POJO's (with JAXB annotations) to XML
	 */
	@Bean
	public ViewResolver jaxb2MarshallingXmlViewResolver() {
		Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
		marshaller.setClassesToBeBound(Pizza.class);
		return new Jaxb2MarshallingXmlViewResolver(marshaller);
	}

	/*
	 * Configure View resolver to provide JSON output using JACKSON library to
	 * convert object in JSON format.
	 */
	@Bean
	public ViewResolver jsonViewResolver() {
		return new JsonViewResolver();
	}
	
	/*
	 * Configure View resolver to provide PDF output using lowagie pdf library to
	 * generate PDF output for an object content
	 */
	@Bean
	public ViewResolver pdfViewResolver() {
		return new PdfViewResolver();
	}

	/*
	 * Configure View resolver to provide XLS output using Apache POI library to
	 * generate XLS output for an object content
	 */
	@Bean
	public ViewResolver excelViewResolver() {
		return new ExcelViewResolver();
	}
	
	/*
	 * Configure View resolver to provide HTML output This is the default format
	 * in absence of any type suffix.
	 */
	@Bean
	public ViewResolver jspViewResolver() {
		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
		viewResolver.setViewClass(JstlView.class);
		viewResolver.setPrefix("/WEB-INF/views/");
		viewResolver.setSuffix(".jsp");
		return viewResolver;
	}
}

Let us look into the above class little deep, First we have created ContentNegotiationManager which is used to determine the requested media types of a request by delegating to a list of ContentNegotiationStrategy instances. By default PathExtensionContentNegotiationStrategy is consulted (which uses the URL extension e.g. .xls, .pdf,.json..) , followed by ParameterContentNegotiationStrategy (which uses the request parameter โ€˜format=xlsโ€™ e.g.), followed by HeaderContentNegotiationStrategy (which uses HTTP Accept Headers) the ContentNegotiationManager instance is injected by Spring Container.
Snippet

@Bean
	public ViewResolver contentNegotiationViewResolver(
			ContentNegotiationManager contentNegotiationManager) {
		ContentNegotiatingViewResolver contentNegotiatingViewResolver = new ContentNegotiatingViewResolver();
		contentNegotiatingViewResolver
				.setContentNegotiationManager(contentNegotiationManager);

once the ContentNegotiationManager instance is ready then we need to pass different implementations of view resolvers in order to resolve dynamically in the runtime.
Snippet:

List<ViewResolver> resolvers = new ArrayList<ViewResolver>();
		resolvers.add(jaxb2MarshallingXmlViewResolver());
		resolvers.add(jsonViewResolver());
		resolvers.add(excelViewResolver());
		resolvers.add(pdfViewResolver());

		contentNegotiatingViewResolver.setViewResolvers(resolvers);
		return contentNegotiatingViewResolver;

There is one more configuration class required inorder to map the request using the front control called “DispatcherServlet”

/**
 * 
 */
package com.spark.spring.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

/**
 * @author Sony
 * 
 */
public class AppInitializer implements WebApplicationInitializer {

	public void onStartup(ServletContext container) throws ServletException {

		AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
		ctx.register(AppConfig.class);
		ctx.setServletContext(container);

		ServletRegistration.Dynamic servlet = container.addServlet(
				"dispatcher", new DispatcherServlet(ctx));

		servlet.setLoadOnStartup(1);
		servlet.addMapping("/");
	}

}

Now let us create different ViewResolver Classes inorder to inject them into ContentNegotiatingViewResolver Object.
Jaxb2MarshallingXmlViewResolver.java

/**
 * 
 */
package com.spark.spring.view.resolvers;

import java.util.Locale;

import org.springframework.oxm.Marshaller;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.xml.MarshallingView;

/**
 * @author Sony
 * 
 */
public class Jaxb2MarshallingXmlViewResolver implements ViewResolver {

	private Marshaller marshaller;

	public Jaxb2MarshallingXmlViewResolver(Marshaller marshaller) {
		this.marshaller = marshaller;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.web.servlet.ViewResolver#resolveViewName(java.lang
	 * .String, java.util.Locale)
	 */
	public View resolveViewName(String viewName, Locale locale)
			throws Exception {
		MarshallingView view = new MarshallingView();
		view.setMarshaller(marshaller);
		return view;
	}

}

JsonViewResolver.java

/**
 * 
 */
package com.spark.spring.view.resolvers;

import java.util.Locale;

import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

/**
 * @author Sony
 * 
 */
public class JsonViewResolver implements ViewResolver {

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.web.servlet.ViewResolver#resolveViewName(java.lang
	 * .String, java.util.Locale)
	 */
	public View resolveViewName(String viewName, Locale locale)
			throws Exception {
		MappingJackson2JsonView view = new MappingJackson2JsonView();
		view.setPrettyPrint(true);
		return view;
	}

}

ExcelViewResolver.java

/**
 * 
 */
package com.spark.spring.view.resolvers;

import java.util.Locale;

import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;

import com.spark.spring.views.GenerateExcel;

/**
 * @author Sony
 *
 */
public class ExcelViewResolver implements ViewResolver {

	/* (non-Javadoc)
	 * @see org.springframework.web.servlet.ViewResolver#resolveViewName(java.lang.String, java.util.Locale)
	 */
	@Override
	public View resolveViewName(String viewname, Locale locale) throws Exception {
		GenerateExcel generateExcel = new GenerateExcel();
		return generateExcel;
	}

}

PdfViewResolver.java

/**
 * 
 */
package com.spark.spring.view.resolvers;

import java.util.Locale;

import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;

import com.spark.spring.views.GeneratePdf;

/**
 * @author Sony
 *
 */
public class PdfViewResolver implements ViewResolver{

	@Override
	public View resolveViewName(String viewName, Locale locale) throws Exception {
		GeneratePdf generatePdf = new GeneratePdf();
		return generatePdf;
	}

}

Below are utility classes for generating Excel content and PDF Content.

GenerateExcel.java

/**
 * 
 */
package com.spark.spring.views;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.web.servlet.view.document.AbstractExcelView;

import com.spark.spring.domain.objects.Pizza;

/**
 * @author Sony
 * 
 */
public class GenerateExcel extends AbstractExcelView {

	@Override
	protected void buildExcelDocument(Map<String, Object> model,
			HSSFWorkbook workbook, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		Pizza pizza = (Pizza) model.get("pizza");

		Sheet sheet = workbook.createSheet("sheet 1");
		CellStyle style = workbook.createCellStyle();
		style.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.index);
		style.setFillPattern(CellStyle.SOLID_FOREGROUND);
		style.setAlignment(CellStyle.ALIGN_CENTER);
		Row row = null;
		Cell cell = null;
		int rowCount = 0;
		int colCount = 0;

		// Create header cells
		row = sheet.createRow(rowCount++);

		cell = row.createCell(colCount++);
		cell.setCellStyle(style);
		cell.setCellValue("Name");

		cell = row.createCell(colCount++);
		cell.setCellStyle(style);
		cell.setCellValue("Flavor");

		cell = row.createCell(colCount++);
		cell.setCellStyle(style);
		cell.setCellValue("Toppings");

		// Create data cells
		row = sheet.createRow(rowCount++);
		colCount = 0;
		row.createCell(colCount++).setCellValue(pizza.getName());
		row.createCell(colCount++).setCellValue(pizza.getFlavor());

		StringBuffer toppings = new StringBuffer("");
		for (String topping : pizza.getToppings()) {
			toppings.append(topping);
			toppings.append(" ");
		}
		row.createCell(colCount++).setCellValue(toppings.toString());

		for (int i = 0; i < 3; i++)
			sheet.autoSizeColumn(i, true);
	}

}

GeneratePdf.java

/**
 * 
 */
package com.spark.spring.views;

import java.awt.Color;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.view.document.AbstractPdfView;

import com.lowagie.text.Document;
import com.lowagie.text.Element;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
import com.spark.spring.domain.objects.Pizza;

/**
 * @author Sony
 *
 */
public class GeneratePdf extends AbstractPdfView{

	@Override
	protected void buildPdfDocument(Map<String, Object> model,
			Document document, PdfWriter writer, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		Pizza pizza = (Pizza) model.get("pizza");

		PdfPTable table = new PdfPTable(3);
		table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
		table.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE);
		table.getDefaultCell().setBackgroundColor(Color.lightGray);

		table.addCell("Name");
		table.addCell("Flavor");
		table.addCell("Toppings");

		table.addCell(pizza.getName());
		table.addCell(pizza.getFlavor());

		StringBuffer toppings = new StringBuffer("");
		for (String topping : pizza.getToppings()) {
			toppings.append(topping);
			toppings.append(" ");
		}
		table.addCell(toppings.toString());
		document.add(table);

	}
}

Now its time for us to write the .JSP file

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"  pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
	<title>Pizza order JSP View</title>
</head>
<body>
	<table border="1">
		<tr>
		<td>NAME</td>
		<td>Flavor</td>
		<td>Toppings</td>
		</tr>
		<tr>
			<td>${pizza.name}</td>
			<td>${pizza.flavor}</td>
			<td>
				<c:forEach var="item" items="${pizza.toppings}">
					<c:out value="${item}"/>&nbsp; 
				</c:forEach>
			</td>
		</tr>
	</table>
</body>
</html>

That is it we have done with our coding, now its time for us to deploy and test.

resp-json

resp-pdf

resp-xml

credits to : http://websystique.com/springmvc/spring-4-mvc-contentnegotiatingviewresolver-example/

Happy Coding With Spring ๐Ÿ™‚

How to create dynamic UI with database config

Hi all here is a small post how to make your user interface(html) dynamically. In the sense just change your database and your user interface changes. the technologies used here are Spring3.x, hibernate3.x and Freemarker
and the specialty here is there is not even a single xml configuration involved.

below are the classes for the spring configuration.

/**
 * 
 */
package com.spark.spring.config;

import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.ClassPathResource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;

/**
 * @author PavanKumar Mantha
 *
 */
@Configuration
@EnableTransactionManagement
@EnableWebMvc
@Import({})
@ComponentScan(basePackages="com.spark.spring")
public class WebApplicationConfig extends WebMvcConfigurerAdapter{

	@Bean
	public FreeMarkerViewResolver getFreeMarkerViewResolver(){
		FreeMarkerViewResolver freeMarkerViewResolver = new FreeMarkerViewResolver();
		freeMarkerViewResolver.setPrefix("");
		freeMarkerViewResolver.setSuffix(".ftl");
		
		return freeMarkerViewResolver;
	}
	
	@Bean
	public FreeMarkerConfigurer getFreeMarkerConfigurer(){
		FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
		freeMarkerConfigurer.setTemplateLoaderPath("/WEB-INF/ftl/");
		return freeMarkerConfigurer;
	}
	
	/*@Bean
	public InternalResourceViewResolver getInternalResourceViewResolver(){
	
		InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
		internalResourceViewResolver.setPrefix("/WEB-INF/jsp/");
		internalResourceViewResolver.setSuffix(".jsp");
		
		return internalResourceViewResolver;
	}*/
	
	@Bean
	public PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer(){
		
		PropertyPlaceholderConfigurer placeholderConfigurer = new PropertyPlaceholderConfigurer();
		placeholderConfigurer.setLocation(new ClassPathResource("application.properties"));
		placeholderConfigurer.setIgnoreUnresolvablePlaceholders(true);
		return placeholderConfigurer;
	}
	
	public void addResourceHandler(ResourceHandlerRegistry resourceHandlerRegistry){
		resourceHandlerRegistry.addResourceHandler("/resources/**").addResourceLocations("/resources");
	}
}

/**
 * 
 */
package com.spark.spring.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

/**
 * @author PavanKumar Mantha
 *
 */
public class WebAppInitializer implements WebApplicationInitializer{

	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {
		AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext();
		annotationConfigWebApplicationContext.register(WebApplicationConfig.class);
		annotationConfigWebApplicationContext.setServletContext(servletContext);
		
		Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(annotationConfigWebApplicationContext));
		dynamic.addMapping("/");
		dynamic.setLoadOnStartup(1);
	}

}

/**
 * 
 */
package com.spark.spring.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;

/**
 * @author PavanKumar Mantha
 * 
 */
@Configuration
public class HibernateConfiguration {

	@Value("${database.driver}")
	private String driverClassName;
	@Value("${database.url}")
	private String url;
	@Value("${database.user}")
	private String username;
	@Value("${database.password}")
	private String password;

	@Value("${hibernate.dialect}")
	private String hibernateDialect;
	@Value("${hibernate.show_sql}")
	private String hibernateShowSql;
	@Value("${hibernate.hbm2ddl.auto}")
	private String hibernateHbm2ddlAuto;

	@Bean
	public DataSource getDataSource() {

		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setDriverClassName(driverClassName);
		dataSource.setUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);

		return dataSource;
	}

	@Bean
	public AnnotationSessionFactoryBean getAnnotationSessionFactoryBean() {
		AnnotationSessionFactoryBean annotationSessionFactoryBean = new AnnotationSessionFactoryBean();
		annotationSessionFactoryBean.setDataSource(getDataSource());
		annotationSessionFactoryBean
				.setHibernateProperties(getHibernateProperties());
		annotationSessionFactoryBean
				.setPackagesToScan(new String[] { "com.spark.spring" });
		return annotationSessionFactoryBean;
	}

	@Bean
	@Autowired
	public HibernateTransactionManager transactionManager(
			SessionFactory sessionFactory) {
		HibernateTransactionManager htm = new HibernateTransactionManager();
		htm.setSessionFactory(sessionFactory);
		return htm;
	}

	@Bean
	@Autowired
	public HibernateTemplate getHibernateTemplate(SessionFactory sessionFactory) {
		HibernateTemplate hibernateTemplate = new HibernateTemplate(
				sessionFactory);
		return hibernateTemplate;
	}

	@Bean
	public Properties getHibernateProperties() {
		Properties properties = new Properties();
		properties.put("hibernate.dialect", hibernateDialect);
		properties.put("hibernate.show_sql", hibernateShowSql);
		properties.put("hibernate.hbm2ddl.auto", hibernateHbm2ddlAuto);

		return properties;
	}

}

Below is the controller that handles the request and deligate the data to freemarker template

/**
 * 
 */
package com.spark.spring.controllers;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.spark.spring.bo.FormFieldsBo;
import com.spark.spring.model.FormFieldsModel;

/**
 * @author PavanKumar Mantha
 *
 */
@Controller
@RequestMapping("/controller")
public class UIRenderingController {

	@Autowired
	FormFieldsBo formFieldsBo;

	@RequestMapping(value = "/renderUi", method = RequestMethod.GET)
	public ModelAndView getTestHit() {
		System.out
				.println("-------------------inside the test hit method-----------------");

		List<FormFieldsModel> formFieldsModels = formFieldsBo.getFormFields("login_form");
		ModelAndView modelAndView = new ModelAndView("login", "formFieldsModels", formFieldsModels);
		return modelAndView;
	}
}

below are the service(BO) object and DataAccess Layer(DAO)

Please note that the below code as both interface and its implementation.

/**
 * 
 */
package com.spark.spring.bo;

import java.util.List;

import com.spark.spring.model.FormFieldsModel;

/**
 * @author PavanKumar Mantha
 *
 */
public interface FormFieldsBo {

	public List<FormFieldsModel> getFormFields(String formId);
}


/**
 * 
 */
package com.spark.spring.bo.impl;

import java.util.List;

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

import com.spark.spring.bo.FormFieldsBo;
import com.spark.spring.dao.FormFieldsDao;
import com.spark.spring.model.FormFieldsModel;

/**
 * @author PavanKumar Mantha
 *
 */
@Service(value="formFieldsBo")
public class FormFieldsBoImpl implements FormFieldsBo{

	@Autowired
	FormFieldsDao formFieldsDao;
	
	@Override
	@Transactional
	public List<FormFieldsModel> getFormFields(String formId) {
		System.out.println("---------------------- inside the BoImpl ----------------------");
		return formFieldsDao.getFormFields(formId);
	}

	
}

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

import java.util.List;

import com.spark.spring.model.FormFieldsModel;

/**
 * @author PavanKumar Mantha
 *
 */
public interface FormFieldsDao {

	public List<FormFieldsModel> getFormFields(String formId);
}

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

import java.util.List;

import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

import com.spark.spring.dao.FormFieldsDao;
import com.spark.spring.model.FormFieldsModel;

/**
 * @author PavanKumar Mantha
 *
 */
@Repository(value="formFieldsDao")
public class FormFieldsDaoImpl implements FormFieldsDao{

	@Autowired
	HibernateTemplate hibernateTemplate;
	
	@Override
	public List<FormFieldsModel> getFormFields(String formId) {

		Query query = hibernateTemplate.getSessionFactory().getCurrentSession().createQuery("from FormFieldsModel f where f.formId = :formId ");
		query.setParameter("formId", formId);
		List<FormFieldsModel> formFields = query.list();
		
		return formFields;
	}

	
}

now here is the freemarker template that gets redered dynamically

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<style>
table a:link {
		color: #666;
		font-weight: bold;
		text-decoration:none;
	}
	table a:visited {
		color: #999999;
		font-weight:bold;
		text-decoration:none;
	}
	table a:active,
	table a:hover {
		color: #bd5a35;
		text-decoration:underline;
	}
	table {
		font-family:Arial, Helvetica, sans-serif;
		color:#666;
		font-size:12px;
		text-shadow: 1px 1px 0px #fff;
		background:#eaebec;
		margin:20px;
		border:#ccc 1px solid;
	
		-moz-border-radius:3px;
		-webkit-border-radius:3px;
		border-radius:3px;
	
		-moz-box-shadow: 0 1px 2px #d1d1d1;
		-webkit-box-shadow: 0 1px 2px #d1d1d1;
		box-shadow: 0 1px 2px #d1d1d1;
		margin-left:auto;
		margin-right:auto;
		margin-top:120px;
	}
	table th {
		padding:21px 25px 22px 25px;
		border-top:1px solid #fafafa;
		border-bottom:1px solid #e0e0e0;
	
		background: #ededed;
		background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#ebebeb));
		background: -moz-linear-gradient(top,  #ededed,  #ebebeb);
	}
	table th:first-child {
		text-align: left;
		padding-left:20px;
	}
	table tr:first-child th:first-child {
		-moz-border-radius-topleft:3px;
		-webkit-border-top-left-radius:3px;
		border-top-left-radius:3px;
	}
	table tr:first-child th:last-child {
		-moz-border-radius-topright:3px;
		-webkit-border-top-right-radius:3px;
		border-top-right-radius:3px;
	}
	table tr {
		text-align: center;
		padding-left:20px;
	}
	table td:first-child {
		text-align: left;
		padding-left:20px;
		border-left: 0;
	}
	table td {
		padding:18px;
		border-top: 1px solid #ffffff;
		border-bottom:1px solid #e0e0e0;
		border-left: 1px solid #e0e0e0;
	
		background: #fafafa;
		background: -webkit-gradient(linear, left top, left bottom, from(#fbfbfb), to(#fafafa));
		background: -moz-linear-gradient(top,  #fbfbfb,  #fafafa);
	}
	table tr.even td {
		background: #f6f6f6;
		background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#f6f6f6));
		background: -moz-linear-gradient(top,  #f8f8f8,  #f6f6f6);
	}
	table tr:last-child td {
		border-bottom:0;
	}
	table tr:last-child td:first-child {
		-moz-border-radius-bottomleft:3px;
		-webkit-border-bottom-left-radius:3px;
		border-bottom-left-radius:3px;
	}
	table tr:last-child td:last-child {
		-moz-border-radius-bottomright:3px;
		-webkit-border-bottom-right-radius:3px;
		border-bottom-right-radius:3px;
	}
	table tr:hover td {
		background: #f2f2f2;
		background: -webkit-gradient(linear, left top, left bottom, from(#f2f2f2), to(#f0f0f0));
		background: -moz-linear-gradient(top,  #f2f2f2,  #f0f0f0);	
	}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script language="javascript">
	$( document ).ready(function() {
		console.log( "ready!" );
		$("#loginButton").click(function(){
			alert('button clicked !');
		});
	});
</script>
</head>
<body>
	<table class="pretty">
		<#list formFieldsModels as formField>
		<tr>
			<#if formField.fieldType == 'text'>
				<td>${formField.fieldLabel}:</td><td><input type="${formField.fieldType}"/><td>
			</#if>
			<#if formField.fieldType == 'password'>
				<td>${formField.fieldLabel}:</td><td><input type="${formField.fieldType}"/></td>
			</#if>
			<#if formField.fieldType == 'button'>
				<td></td><td><input type="${formField.fieldType}" value="${formField.fieldLabel}" id="loginButton"/></td>
			</#if>
		</tr>
		</#list>
	</table>
</body>
</html>

here is the screenshots of the database and the final output.
database

login_ui

Happy Coding (Dynamic UI) ๐Ÿ™‚

Handling Oracle Stored Procedures with Arrays or Table Types in Spring

Hello guys, in this post lets discuss how to handle oracle procedure that take custom or array types as input params and return array type or table type as out param.

this example has been tested with spring 3.2.x and with oracle 10g xe.
note : run the below scripts in oracle to create objects prior to coding java.

-- custom type
create or replace TYPE "KEYVALUEOBJECT"
as object(name varchar(255),
value varchar(255));
================================================================

-- array of KeyValueObject
create or replace
TYPE "MY_OBJECT_ARRAY"
as table of KeyValueObject;

================================================================
-- this proc, doesn't do too much
create or replace
procedure Sample_Proc(
i_array in MY_OBJECT_ARRAY,
o_array out MY_OBJECT_ARRAY)
as
begin
o_array := MY_OBJECT_ARRAY();
for i in 1 .. i_array.count loop

o_array.extend;
o_array(i) := KeyValueObject(i_array(i).name, i_array(i).value);
end loop;
end;

applicationContext.java

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:jms="http://www.springframework.org/schema/jms" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<bean id="propertyPlaceholderConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>jdbc.properties</value>
			</list>
		</property>
	</bean>

	<bean id="springDataSource"
		class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
		<property name="driverClassName" value="${db.driver}" />
		<property name="url" value="${db.url}" />
		<property name="username" value="${db.user}" />
		<property name="password" value="${db.password}" />
	</bean>

	<bean id="keyValueDao" class="com.spring.jdbc.dao.tab.type.impl.KeyValueDaoImpl">
		<constructor-arg name="dataSource" ref="springDataSource"></constructor-arg>
	</bean>

</beans>

KeyValueDao.java

package com.spring.jdbc.dao;

import com.sparing.jdbc.pojo.KeyValueObject;

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

	public KeyValueObject[] getKeyValueObjects(KeyValueObject[] keyValueObjects);
	
}

KeyValueDaoImpl.java

/**
 * 
 */
package com.spring.jdbc.dao.tab.type.impl;

import javax.sql.DataSource;

import com.sparing.jdbc.pojo.KeyValueObject;
import com.spring.jdbc.dao.KeyValueDao;

/**
 * @author Sony
 *
 */
public class KeyValueDaoImpl extends TableTypeBaseProcedure implements KeyValueDao{

	public KeyValueDaoImpl(DataSource dataSource) {
		super(dataSource);
	}

	@Override
	public KeyValueObject[] getKeyValueObjects(KeyValueObject[] keyValueObjects) {
		
		return execute(keyValueObjects);
		
	}

}

the main business logic exist in this class.
TableTypeBaseProcedure.java

/**
 * 
 */
package com.spring.jdbc.dao.tab.type.impl;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import oracle.sql.ARRAY;

import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.SqlReturnType;
import org.springframework.jdbc.object.StoredProcedure;

import com.sparing.jdbc.pojo.KeyValueObject;

/**
 * @author Sony
 * 
 */
public class TableTypeBaseProcedure extends StoredProcedure {

	private static final String PROC_NAME = "Sample_Proc";
	private static final String TAB_TYPE = "KEYVALUEOBJECT";
	
	private static final String MY_ARRAY = "MY_OBJECT_ARRAY";
	private static final String I_ARRAY = "input_array";
	private static final String O_ARRAY = "output_array";


	public TableTypeBaseProcedure(DataSource dataSource) {
		
		super(dataSource, PROC_NAME);
		
		declareParameter(new SqlParameter(I_ARRAY, Types.ARRAY, MY_ARRAY));
		declareParameter(new SqlOutParameter(O_ARRAY, Types.ARRAY, MY_ARRAY,
				new SqlReturnType() {

					@Override
					public Object getTypeValue(CallableStatement cs,
							int paramIndex, int sqlType, String typeName)
							throws SQLException {
						Connection connection = cs.getConnection();
						Map<String, Class<?>> typeMap = connection.getTypeMap();
						typeMap.put(TAB_TYPE, KeyValueObject.class);
						return cs.getObject(paramIndex);
					}
				}));
		compile();
	}

	public KeyValueObject[] execute(KeyValueObject[] keyValueObjects) {
		Map<String, Object> params = new HashMap<>();
		params.put(I_ARRAY, new KeyValueSqlType(keyValueObjects));

		Map<?, ?> result = execute(params);

		if ((!result.containsKey(O_ARRAY) || result.get(O_ARRAY) == null)) {
			return null;
		}

		try {
			Object[] resultArray = (Object[]) ((ARRAY) result.get(O_ARRAY))
					.getArray();

			return Arrays.copyOf(resultArray, resultArray.length,
					KeyValueObject[].class);
		} catch (SQLException e) {
			throw new DataRetrievalFailureException("Unable to retrieve array",
					e);
		}
	}

}

this is a helper class
KeyValueSqlType.java

/**
 * 
 */
package com.spring.jdbc.dao.tab.type.impl;

import java.sql.Connection;
import java.sql.SQLException;

import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;

import org.springframework.jdbc.core.support.AbstractSqlTypeValue;

import com.sparing.jdbc.pojo.KeyValueObject;

/**
 * @author Sony
 *
 */
public class KeyValueSqlType extends AbstractSqlTypeValue{

	private KeyValueObject[] keyValueObjects;
	
	public KeyValueSqlType(KeyValueObject[] keyValueObjects) {
		this.keyValueObjects = keyValueObjects;
	}
	
	@Override
	protected Object createTypeValue(Connection connection, int sqlType,
			String typeName) throws SQLException {
		
		ArrayDescriptor arrayDescriptor = new ArrayDescriptor(typeName, connection);
		return new ARRAY(arrayDescriptor,connection,keyValueObjects);
	}

}

The main domain object that will flow in and out to database.
KeyValueObject.java

/**
 * 
 */
package com.sparing.jdbc.pojo;

import java.sql.SQLData;
import java.sql.SQLException;
import java.sql.SQLInput;
import java.sql.SQLOutput;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

/**
 * @author Sony
 * 
 */
public class KeyValueObject implements SQLData {

	private String name;
	private String value;

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the value
	 */
	public String getValue() {
		return value;
	}

	/**
	 * @param value
	 *            the value to set
	 */
	public void setValue(String value) {
		this.value = value;
	}

	@Override
	public String getSQLTypeName() throws SQLException {
		return "KeyValueObject";
	}

	@Override
	public void readSQL(SQLInput stream, String typeName) throws SQLException {

		name = stream.readString();
		value = stream.readString();
	}

	@Override
	public void writeSQL(SQLOutput stream) throws SQLException {

		stream.writeString(name);
		stream.writeString(value);
	}

	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this,
				ToStringStyle.SHORT_PREFIX_STYLE);
	}

}

Happy Coding ๐Ÿ™‚
Happy Oracle Stored Procedures with Arrays or Table Types in Spring ๐Ÿ™‚

Consuming web service using Spring 3.x

Hi guys, Here i am going to demonstrate how to consume web service using spring framework.Consuming web services with Spring framework is amazingly easy. It avoids the need of creating client side stubs during compile time and does the same at run time. A typical web service client can be configured as shown below-

inorder to get the spring capability for webservice please add the following dependencies to pom.xml as below-

<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.webservice</groupId>
  <artifactId>SpringWebService</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>SpringWebService</name>
  <description>SpringWebService</description>
  
  <dependencies>
  	<dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-core</artifactId>
  		<version>3.1.1.RELEASE</version>
  	</dependency>
  	<dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-context</artifactId>
  		<version>3.1.1.RELEASE</version>
  	</dependency>
  	<dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-context-support</artifactId>
  		<version>3.1.1.RELEASE</version>
  	</dependency>
  	<dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-beans</artifactId>
  		<version>3.1.1.RELEASE</version>
  	</dependency>
  	<dependency>
  		<groupId>org.springframework.ws</groupId>
  		<artifactId>spring-ws-core</artifactId>
  		<version>2.1.1.RELEASE</version>
  	</dependency>
  </dependencies>
</project>

please configure your applicationContext.xml as below-

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

	<bean id="myWebService"
		class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
		<property name="serviceInterface" value="com.spark.webservice.TemperatureConverter" />
		<property name="wsdlDocumentUrl" value="http://localhost:8080/JBossWebServices?wsdl" />
		<property name="namespaceUri" value="http://impl.webservice.spark.com/" />
		<property name="serviceName" value="TemperatureConverter" />
		<property name="portName" value="TemperatureConverterImplPort" />
	</bean>

</beans>

Where serviceInterface is the business interface that clients will use for invoking service methods. wsdlDocumentUrl is the URL for the published WSDL file. Spring will download WSDL from the given URL and generate the client side stubs when it creates the bean usually during application start up. namespaceUri corresponds to the targetNamespace in the .wsdl file. serviceName corresponds to the service name in the .wsdl file. portName corresponds to the port name in the .wsdl file.

Note Please refer to my previous port to get the wsdl file.

Now accessing web service pretty easy, just get the bean from Spring context and use that to invoke methods-

/**
 * 
 */
package com.spark.spring.webservice.client;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.spark.webservice.TemperatureConverter;

/**
 * @author Sony
 *
 */
public class SpringWebserviceClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		TemperatureConverter converter = (TemperatureConverter)applicationContext.getBean("myWebService");
		System.out.println(converter.convertCelsiusToFahrenheit(42.0));
	}

}

inorder to use the service we need to create the service interface type as below –

/**
 * 
 */
package com.spark.webservice;

import javax.jws.WebMethod;
import javax.jws.WebService;

/**
 * @author Sony
 *
 */
@SuppressWarnings("restriction")
@WebService
public interface TemperatureConverter {

	@WebMethod
	public double convertCelsiusToFahrenheit(double value);
	@WebMethod
	public double convertFahrenheitToCelsius(double value);
}

Thats it now run the main method and get the result.
Note: the service should be up and running in the server.

Happy Coding ๐Ÿ™‚

Spring Integration with JPA/Hibernate using maven – I

Hi all here is my post regarding integration of some of the best frameworks available in the market, Spring+JPA/Hibernate.
Springโ€™s Basic concept: Inversion of Control

The basic concept of spring is the Inversion of Control pattern (dependency injection). In Spring, programmers donโ€™t need to create user objects but they need to describe how they should be created (in applicationContext.xml or using annotations). Programmers need not directly connect components and services together in code but describe which services are needed by which components in a configuration file or using annotations. The spring container is responsible for all this. Spring creates all the objects, connects them together by setting the necessary properties, and determines when methods will be invoked.
So using Spring framework the integration between technologies become loosely coupled.

Requirements:
Spring 3.1
JPA2.x/Hibernate 3.x
Eclipse 4.2 with Maven
Mysql Database

The major parts of the Credentials application explained below are:

The Entity classes
The DAO class which will contain common db operation code and functions
The service class โ€“ which is the actual business class.. This will contain actual business logic in it. In our example, we save Credentials bean information using this class.
Explained in the next tutorial
The client โ€“ The client can be a jsp / jsf web components or it can be a simple java program, which gets the service bean from spring and calls business method.
The springโ€™s applicationContext.xml descriptor which specifies what are the objects to be created when starting the application and where they should be injected.

Letโ€™s go through the tutorial step by step.You can download the full project code at the end of the tutorial:
i explain how to Retrieve and Insert and leave Delete and Update to be coded yourself(for fun).

Step1:create a maven project in eclipse.
step2:update the pom.xml file as shown below.

<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</groupId>
	<artifactId>SpringIntegration</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>SpringIntegration</name>
	<description>SpringIntegration</description>

	<properties>
		<org.slf4j-version>1.6.1</org.slf4j-version>
	</properties>

	<dependencies>

		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>2.2</version>
		</dependency>
		<dependency>
			<groupId>net.sf.ezmorph</groupId>
			<artifactId>ezmorph</artifactId>
			<version>1.0.6</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>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.18</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.1</version>
		</dependency>
		<dependency>
			<groupId>commons-httpclient</groupId>
			<artifactId>commons-httpclient</artifactId>
			<version>3.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>3.1.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>3.1.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>3.1.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-expression</artifactId>
			<version>3.1.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>3.1.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>3.1.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>3.1.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>3.1.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>3.1.1.RELEASE</version>
		</dependency>
		<!-- Spring Security -->
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>3.1.0.RELEASE</version>
			<exclusions>
				<!-- Exclude Commons Logging in favor of SLF4j -->
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-taglibs</artifactId>
			<version>3.1.0.RELEASE</version>
			<exclusions>
				<!-- Exclude Commons Logging in favor of SLF4j -->
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-config</artifactId>
			<version>3.1.0.RELEASE</version>
			<exclusions>
				<!-- Exclude Commons Logging in favor of SLF4j -->
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-crypto</artifactId>
			<version>3.1.0.RELEASE</version>
		</dependency>

		<!-- Logging -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${org.slf4j-version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.16</version>
			<scope>runtime</scope>
		</dependency>

		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>1.6.10</version>
		</dependency>


		<!-- @Inject -->
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>

		<!-- Servlet -->
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<!-- Hibernate Validator -->
		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>1.0.0.GA</version>
		</dependency>

		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>4.2.0.CR1</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>3.4.0.GA</version>
		</dependency>
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.2.2</version>
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.2</version>
		</dependency>
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.4</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>3.1.1.RELEASE</version>
		</dependency>

	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>tomcat-maven-plugin</artifactId>
				<version>1.0-beta-1</version>
			</plugin>
			<plugin>
				<groupId>org.mortbay.jetty</groupId>
				<artifactId>jetty-maven-plugin</artifactId>
				<version>7.4.0.v20110414</version>
				<configuration></configuration>
			</plugin>
		</plugins>
		<pluginManagement>
			<plugins>
				<!--This plugin's configuration is used to store Eclipse m2e settings 
					only. It has no influence on the Maven build itself. -->
				<plugin>
					<groupId>org.eclipse.m2e</groupId>
					<artifactId>lifecycle-mapping</artifactId>
					<version>1.0.0</version>
					<configuration>
						<lifecycleMappingMetadata>
							<pluginExecutions>
								<pluginExecution>
									<pluginExecutionFilter>
										<groupId>
											org.apache.maven.plugins
										</groupId>
										<artifactId>
											maven-compiler-plugin
										</artifactId>
										<versionRange>
											[2.3.2,)
										</versionRange>
										<goals>
											<goal>compile</goal>
											<goal>testCompile</goal>
										</goals>
									</pluginExecutionFilter>
									<action>
										<ignore></ignore>
									</action>
								</pluginExecution>
							</pluginExecutions>
						</lifecycleMappingMetadata>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>
	<!-- needed for XmlSchema -->
	<repositories>
		<repository>
			<id>ibiblio</id>
			<name>ibiblio maven repository</name>
			<url>http://ibiblio.org/maven/</url>
			<layout>legacy</layout>
		</repository>
		<repository>
			<id>apache</id>
			<name>Apache maven repository</name>
			<url>http://www.apache.org/dist/java-repository/</url>
			<layout>legacy</layout>
		</repository>
	</repositories>

</project>

Step3:put web.xml in src/main/webapp/WEB-INF/ as shown below.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- Defines all the spring context information for all servlets and Filters 
		that share the info -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:application-context.xml</param-value>
	</context-param>

	<!-- creates spring container listener shared by all servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- request processing servlet -->
	<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>pages/index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

put all the configuration files in the src/main/resources folder of your maven project.

Step4: lets code our first configuration file “application-context.xml” as shown below.

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
			http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

	<!-- component scan for @component,@Repositry,@Service -->
	<context:component-scan base-package="com.spark" />
	
	<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>

	<!-- JPA EntityManagerFactory -->
	<bean id="entityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
		p:dataSource-ref="dataSource">
		<property name="persistenceUnitName" value="MyPersistenceUnit"/> 
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<property name="database" value="MYSQL" />
				<property name="showSql" value="true" />
			</bean>
		</property>
	</bean>

	<!-- Transaction manager for a single JPA EntityManagerFactory (alternative 
		to JTA) -->
	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
		p:entityManagerFactory-ref="entityManagerFactory" />

	<!-- Activates various annotations to be detected in bean classes for eg 
		@Autowired -->
	<context:annotation-config />

	<!-- enable the configuration of transactional behavior based on annotations -->
	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

	<!-- Property Configurator -->
	<bean id="propertyConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="location" value="classpath:jdbc.properties" />
	</bean>

</beans>

Step5:lets code our second configuration file “spring-context.xml” which internally imports one more configuration file “controllers.xml”, this spring-context.xml file goes as a parameter for DispatcherServlet class of Spring framework.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
        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
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

	<!-- Enables the Spring MVC @Controller programming Model -->
	<annotation-driven />

	<beans:bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/" />
		<beans:property name="suffix" value=".html" />
	</beans:bean>

	<!-- Imports user-defined @Controller beans that process client requests -->
	<beans:import resource="controllers.xml" />

</beans:beans>

Step6: controllers.xml

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

	<!-- Activates various annotations to be detected in bean classes -->	
	<context:annotation-config />
	<context:spring-configured />
	<!-- enable the configuration of transactional behavior based on annotations -->
	<tx:annotation-driven/>

	<!-- Scans within the base package of the application for @Components to configure as beans -->
	<context:component-scan base-package="com.spark" />
	
	
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- one of the properties available; the maximum file size in bytes -->
		<property name="maxUploadSize" value="10000000" />
	</bean>
	
	
</beans>

Step7: Lets put the log4j.properties


log4j.rootCategory=debug, stdout, logfile

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n

log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=C://templog/clinicComponet.log
log4j.appender.logfile.MaxFileSize=1MB

# Keep three backup files
log4j.appender.logfile.MaxBackupIndex=3
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout

#Pattern to output : date priority [category] - <message>line_separator
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - <%m>%n

So now we have finished coding our configuration just start with our logic
create the followiing packages in src/main/java folder of maven project as follows.

com.spark.controller
com.spark.dao
com.spark.service
com.spark.model

Lets start coding Java now. first step is coding our model class(POJO) as below.

/**
 * 
 */
package com.spark.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

/**
 * @author Sony
 * 
 */

@Entity
@Table(name = "credentials")
@NamedQueries({
@NamedQuery(name="Credentials.getAllRecords",
    query="SELECT o FROM Credentials o")          
})
public class Credentials implements Serializable{

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "ID")
	private int id;

	@Column(name = "username")
	private String username;

	@Column(name = "password")
	private String password;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
}

once our pojo is ready lets decide the business logic that is our service class. we will code an interface and its implementation class as follows

/**
 * 
 */
package com.spark.service;

import java.util.List;

import com.spark.model.Credentials;

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

    void save(Credentials credentials);
    Credentials findById(Long id);       
    List<Credentials> findAll();   
}

and following is the implementation class

/**
 * 
 */
package com.spark.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.spark.dao.CredentialsDao;
import com.spark.dao.CredentialsDaoImpl;
import com.spark.model.Credentials;

/**
 * @author Sony
 *
 */
@Service("credentialService")
public class CredentialsServiceImpl implements CredentialsService {

	@Autowired
	CredentialsDao credentialsDao;
	
	public CredentialsDao getCredentialsDao() {
		return credentialsDao;
	}

	public void setCredentialsDao(CredentialsDao credentialsDao) {
		this.credentialsDao = credentialsDao;
	}

	/* (non-Javadoc)
	 * @see com.spark.service.CredentialsService#save(com.spark.model.Credentials)
	 */
	@Override
	public void save(Credentials credentials) {
		// TODO Auto-generated method stub
		credentialsDao.save(credentials);

	}

	/* (non-Javadoc)
	 * @see com.spark.service.CredentialsService#findById(java.lang.Long)
	 */
	@Override
	public Credentials findById(Long id) {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see com.spark.service.CredentialsService#findAll()
	 */
	@Override
	public List<Credentials> findAll() {
		// TODO Auto-generated method stub
		return credentialsDao.findAll();
	}

}

Now its time to code our core database logic. The database logic is handled by JPA EntityManager, the object is injected into the EntityManager using the @PersistenceContext annotation its the responsibility of the Spring container to inject the EntityManager Implementation object after it scans the annotation. We will code the dao layer same as we did with service layer with an interface and its implementation class. please note that the dao is annotated as @Transactional that means the database operations will be executed under a transactional context
when spring scans the annotation.

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

import java.util.List;

import com.spark.model.Credentials;

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

    public List<Credentials> findAll();
    public void save(Credentials credentials);
    public Credentials findById(int id);

}

following is the implementation class for the interface.

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

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.spark.model.Credentials;

/**
 * @author Sony
 *
 */
@Transactional
@Component
public class CredentialsDaoImpl implements CredentialsDao {
	
	@PersistenceContext
	private EntityManager entityManager;

	public EntityManager getEntityManager() {
		return entityManager;
	}

	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	/* (non-Javadoc)
	 * @see com.spark.dao.CredentialsDao#findAll()
	 */
	@Override
	public List<Credentials> findAll() {
		// TODO Auto-generated method stub
		List<Credentials> credentials = null;
		try {
			credentials = entityManager.createNamedQuery("Credentials.getAllRecords").getResultList();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return credentials;
	}

	/* (non-Javadoc)
	 * @see com.spark.dao.CredentialsDao#save(com.spark.model.Credentials)
	 */
	@Override
	public void save(Credentials credentials) {
		// TODO Auto-generated method stub
		try {
			
			entityManager.persist(credentials);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	/* (non-Javadoc)
	 * @see com.spark.dao.CredentialsDao#findById(int)
	 */
	@Override
	public Credentials findById(int id) {
		// TODO Auto-generated method stub
		return null;
	}

}

Now its time to code controller which is responsible for deligating the requests to service layer and there to dao layer. In the retrieve method the response returned from the method will be a JSON String

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

import java.util.List;

import javax.validation.Valid;

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.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.spark.model.Credentials;
import com.spark.service.CredentialsService;

/**
 * @author Sony
 *
 */
@Controller
public class SpringController {

	@Autowired(required=true)
	CredentialsService credentialsService;
	
	@RequestMapping(value="/insert",method=RequestMethod.POST)
	public @ResponseBody String handleInsertRequest(@Valid String username,@Valid String password){
		
		String returnStatus = "Details Saved Successfully";
				
		Credentials credentials = new Credentials();
		credentials.setUsername(username);
		credentials.setPassword(password);
		
		credentialsService.save(credentials);
		
		return returnStatus;
	}
	
	@RequestMapping(value="/retrieve",method=RequestMethod.POST)
	public @ResponseBody String handleRetrieveRequest(){
				
		List<Credentials> credentials = credentialsService.findAll();
		
		JSONObject responseDetailsJson = new JSONObject();
	    JSONArray jsonArray = new JSONArray();

	    for (int i = 0; i < credentials.size(); i++)
	    {
	      JSONObject formDetailsJson = new JSONObject();
	      formDetailsJson.put("username", credentials.get(i).getUsername());
	      formDetailsJson.put("password", credentials.get(i).getPassword());

	      jsonArray.add(formDetailsJson);
	    }
	    responseDetailsJson.put("credentials", jsonArray);
	    
	    return responseDetailsJson.toString();
		
	}
}

I will post the the UI related stuff(JSP) in the next tutorial to call the controller.

Happy Coding ๐Ÿ™‚