Aspect Oriented Programming – Advices

Aspect oriented Programming is a cross cutting concepts to OOP. AOP in Spring is used in replacement to EJB for it’s declarative programming style. in this tutorial we will look into different advices that AspectJ supports in Spring.

First of all an Advice is a functionality that we want to execute before or after some method is getting executed.
There are 4 types of Advices that Spring Supports.

  • BeforeAdvice : this advice is executed before every method call
  • AfterAdvice : this advice is executed after every method call. please note that this will not get executed if a method throws some exception
  • AfterThrowingAdvice : this advice is executed after every method throws some configured exceptions
  • AroundAdvice : this advice is executed before and after every method call

let us dive directly to code part as the above explanation is straight forward.
Step1: Let us look into POM.xml file

<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.aop</groupId>
	<artifactId>AOPTutorial</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>AOPTutorial</name>
	<description>AOPTutorial</description>

	<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.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>1.8.5</version>
		</dependency>
		<dependency>
			<groupId>aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.5.4</version>
		</dependency>
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>3.1</version>
		</dependency>
	</dependencies>

	<properties>
		<spring.version>4.1.8.RELEASE</spring.version>
	</properties>
</project>

Step2: let us look into our application-context.xml file, which acts as the spring configuration file.

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

	<bean id="customerService" class="com.spark.aop.service.CustomerService">
		<property name="customerId" value="10"></property>
	</bean>

	<bean id="beforeAdvice" class="com.spark.aop.advice.BeforeAdvice" />
	<bean id="afterAdvice" class="com.spark.aop.advice.AfterAdvice" />
	<bean id="throwAdvice" class="com.spark.aop.advice.ThrowAdvice" />

	<bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

		<property name="target" ref="customerService" />

		<property name="interceptorNames">
			<list>
				<value>beforeAdvice</value>
				<value>afterAdvice</value>
				<value>throwAdvice</value>
			</list>
		</property>
	</bean>
</beans>

now let us start writing the classes that were shown in the above configuration file.
Step3: write a class named BeforeAdvice.java which will implement MethodBeforeAdvice.java interface. this interface has before method which gets executed before every method call

package com.spark.aop.advice;

import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;

/**
 * @author Sony
 *
 */
public class BeforeAdvice implements MethodBeforeAdvice {
	public void before(Method method, Object[] args, Object target) throws Throwable {
		System.out.println("BeforeAdvice class : Before method !");
	}
}

Step4: Now let us write the service class as shown below, which has got some specific operations to be done.

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

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

	private int customerId;

	public int getCustomerId() {
		return customerId;
	}

	public void setCustomerId(int customerId) {
		this.customerId = customerId;
	}

	public void getCustomerById() {
		System.out.println("******* CustomerService*********"+customerId);
	}
	
	public void getException() throws IllegalArgumentException {
		 throw new IllegalArgumentException();
	}
}

Step5: finally let us code our main program through which we can start test our advice functionality.

package com.spark.aop.main;

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

import com.spark.aop.service.CustomerService;

public class App {
	public static void main(String[] args) {
		ApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] { "application-context.xml" });

		CustomerService cust = (CustomerService) appContext.getBean("customerServiceProxy");

		System.out.println("************Main Method*************");
		cust.getCustomerById();
		System.out.println("************Going to throw Exception*************");
		try {
			cust.getException();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		
	}
}

Misc : the code for AfterAdvice.java and ThrowAdvice.java are given below.

/**
 * 
 */
package com.spark.aop.advice;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

/**
 * @author Sony
 *
 */
public class AfterAdvice implements AfterReturningAdvice {

	public void afterReturning(Object object, Method method, Object[] objects, Object object2) throws Throwable {
		
		System.out.println("AfterAdvice class : After method !");
	}

}

/**
 * 
 */
package com.spark.aop.advice;

import org.springframework.aop.ThrowsAdvice;

/**
 * @author Sony
 *
 */
public class ThrowAdvice implements ThrowsAdvice{

	public void afterThrowing(IllegalArgumentException e) throws Throwable {
		System.out.println("ThrowAdvice class : Method Thrown exception !");
	}
}

That’s it guys we have finished coding advices in spring.
practical scenario : this kind of approach is very much useful while writing logging facility in projects.
please test the code on your own, and let me know if anything is needed.

Happy Advices πŸ™‚

Advertisements

Using SpringBoot , SpringData and MongoDB

Hello everybody, its a long gap that i have not written a post in my blog. This post could be my last post in 2015. today we are going to see how to integrate Spring’s one of the best feature Spring Boot with Spring data and MongoDB.

Spring Boot:(courtesy Spring.io) Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”. Most Spring Boot applications need very little Spring configuration.


Features:

  • Create stand-alone Spring applications
  • Embed Tomcat, Jetty
  • Automatically configure Spring whenever possible
  • Absolutely no code generation and no requirement for XML configuration

Now let us create a project that can integrate the above mentioned technology stack.
spring-boot-proj

Step 1: create the mongo-db.properties file in src/main/resources folder

MONGO_DB_HOST=127.0.0.1
MONGO_DB_PORT=27017
DB=school

Step 2: create the application configuration java class which is responsible for creating the MongoTemplate object. below is AppConfig.java

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

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
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.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

import com.mongodb.Mongo;
import com.mongodb.MongoClient;

/**
 * @author Sony
 *
 */
@Configuration
@PropertySource(value = "classpath:mongo-config.properties")
public class AppConfig {

	@Value("${MONGO_DB_HOST}")
	private String MONGO_DB_HOST;

	@Value("${MONGO_DB_PORT}")
	private int MONGO_DB_PORT;

	@Value("${DB}")
	private String DB;

	protected String getDatabaseName() {
		return DB;
	}

	@Bean
	public Mongo getMongo() throws Exception {
		return new MongoClient(MONGO_DB_HOST, MONGO_DB_PORT);
	}

	@Bean
	public MongoDbFactory mongoDbFactory() throws Exception {
		return new SimpleMongoDbFactory(getMongo(), getDatabaseName());
	}

	@Bean
	public MongoTemplate mongoTemplate() throws Exception {

		MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());

		return mongoTemplate;

	}
}

Step 3: create the pojo classes which are mapped as documents in mongodb. below are the Student.java and Score.java respectively

/**
 * 
 */
package com.spark.spring.practice.beans;

import java.util.List;

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

/**
 * @author Sony
 *
 */
@Document(collection = "students")
public class Student {

	@Id
	private int _id;
	@Field(value="name")
	private String name;
	@Field(value="scores")
	List<Score> scores;

	public int get_id() {
		return _id;
	}

	public void set_id(int _id) {
		this._id = _id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<Score> getScores() {
		return scores;
	}

	public void setScores(List<Score> scores) {
		this.scores = scores;
	}

}

/**
 * 
 */
package com.spark.spring.practice.beans;

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

	private String type;
	private double score;

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public double getScore() {
		return score;
	}

	public void setScore(double score) {
		this.score = score;
	}

}

Step 4: create the controller class which can handle the request coming from client. in this example the controller is called GlobalController.java. The controller class is autowired with MongoTemplate Object and StudentRepository, so let us create StudentRepository so that it will get injected into the controller, when the class loads to spring container. MongoTemplate is readily configured in the AppConfig.java file.

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

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.spark.spring.practice.beans.Student;
import com.spark.spring.practice.repositories.StudentRepository;

/**
 * @author Sony
 *
 */
@RestController
@RequestMapping(value = "/rest/v1/students")
public class GlobalController {
	
	Logger logger = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private MongoTemplate mongoTemplate;
	
	@Autowired
	private StudentRepository studentRepository;

	@RequestMapping(value = "/findall", method = RequestMethod.GET)
	public List<Student> getAllStudents() {
		List<Student> students = studentRepository.findAll();
		return students;
	}
}

Step 5: create the repository interface which will extend the MongRepository<T,ID> interface from spring library.

/**
 * 
 */
package com.spark.spring.practice.repositories;

import org.springframework.data.mongodb.repository.MongoRepository;

import com.spark.spring.practice.beans.Student;

/**
 * @author Sony
 *
 */
public interface StudentRepository extends MongoRepository<Student, Integer> {

}

Step 6: create the main class which will act as booting mechanism and will start the project with the help of @SpringBootApplication & @EnableMongoRepositories annotations

/**
 * 
 */
package com.spark.spring.practice.main;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

/**
 * @author Sony
 *
 */
@SpringBootApplication
@ComponentScan(basePackages={"com.spark.spring.practice"})
@EnableMongoRepositories(basePackages={"com.spark.spring.practice"})
public class SpringBootMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		SpringApplication.run(SpringBootMain.class, args);
	}

}

that’s all guys we are done with coding part. Its time for us to run the project. once you ran the project with out errors then below is the kind of output that can be seen on console.
Spring-boot-console

now open the REST-client add-on either in chrome or firefox and test your services.
Happy Spring-booting πŸ™‚

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 πŸ™‚

Pushing Data to Apache Solr Using SpringData

From past few days i was working on Apache Solr Technologies to index data in one of my projects. Today i wanted to elaborate on this concept, this post assumes that you already have Apache Solr installed on your system, if not please install the latest( > 4.1) version from here. Read the instruction from solr site make the Solr server up and running. Once this Solr is up and running we can go to Admin dashboard by hitting the following url http://localhost:8983/solr.

Now its time for us to dive into Spring coding inorder to push data to solr server. this project is written on top of Spring4, SpringData, Solr4, Maven and Eclipse Luna.

first lets create a maven project and put the below code in your pom.xml file and the project structure looks as below.

SolrProjectStructure

<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.solr</groupId>
	<artifactId>SolrSpringIntegration</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>SolrSpringIntegration</name>
	<description>SolrSpringIntegration</description>
	<properties>
		<jdk.version>1.6</jdk.version>
		<spring.version>4.0.4.RELEASE</spring.version>
		<spring.security.version>3.2.3.RELEASE</spring.security.version>
		<jstl.version>1.2</jstl.version>
		<spring-data-solr.verion>1.3.0.RELEASE</spring-data-solr.verion>
	</properties>

	<dependencies>

		<!-- Spring dependencies -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</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</groupId>
			<artifactId>spring-oxm</artifactId>
			<version>${spring.version}</version>
		</dependency>

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

		<!-- SOLR -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-solr</artifactId>
			<version>${spring-data-solr.verion}</version>
		</dependency>

		<!-- jstl and servlet for jsp page -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
		</dependency>
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
			<version>${jstl.version}</version>
		</dependency>

		<!-- json lib -->
		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
			<classifier>jdk15</classifier>
		</dependency>

		<!-- mysql dependency -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.9</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.7</version>
		</dependency>


	</dependencies>
	<build>
		<finalName>spark-solr</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Now its time for to start with the configurations and let me remind since we are using Spring for as the core framework i will make use of Java configuration capability of Spring. so all my configurations are just java codes with out xml files. let us start with database config first
DBConfig.java

/**
 * 
 */
package com.spark.solr.web.config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

/**
 * @author Sony
 *
 */
@Configuration
public class DBConfig {

	@Value("${db.driverClass}")
	String driverClassName;
	@Value("${db.url}")
	String url;
	@Value("${db.username}")
	String username;
	@Value("${db.password}")
	String password;
	
	@Bean
	public DataSource getDataSource(){
		DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
		driverManagerDataSource.setDriverClassName(driverClassName);
		driverManagerDataSource.setUrl(url);
		driverManagerDataSource.setUsername(username);
		driverManagerDataSource.setPassword(password);
		
		return driverManagerDataSource;
	}
	
	@Bean
	public JdbcTemplate getJdbcTemplate(DataSource dataSource){
		return new JdbcTemplate(dataSource);
	}
}

The above code is responsible for injecting the database properties and creating the datasource and finally injecting datasource into jdbc template class.
Now let us write the solr configuration integrated to spring.
SolrConfiguration.java

/**
 * 
 */
package com.spark.solr.web.config;

import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.web.client.RestTemplate;

/**
 * @author Sony
 *
 */
@Configuration
public class SolrConfiguration {

	@Value("${solr.server.host}")
	private String solrUrl;
	
	@Bean
	public SolrTemplate getSolrTemplate(SolrServer server){
		SolrTemplate solrTemplate = new SolrTemplate(server);
		return solrTemplate;
	}
	
	@Bean
	public SolrServer getSolrServer(){
		System.out.println("--------->"+solrUrl);
		SolrServer solrServer = new HttpSolrServer(solrUrl);
		return solrServer;
	}
	
}

Above class is responsible for creating the Solr Server object and injecting that to SolrTemplate class, using which we can perform operation over solr server. now to make our project web compatible lets code WebApplication initializer as below which acts similar to web.xml, this works only with servlet 3.0 container (tomcat7 and above)

/**
 * 
 */
package com.spark.solr.web.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 Sony
 *
 */
public class WebAppInitializer implements WebApplicationInitializer{

	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("/solr/*");
		dynamic.setLoadOnStartup(1);
		
		
	}

}

Below is the global config file to read the property files and to load other config files also the below code is responsible for detecting different annotations.

/** 
 * 
 */
package com.spark.solr.web.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.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * @author Sony
 *
 */
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.spark.solr")
@Import({ SolrConfiguration.class, DBConfig.class })
public class WebApplicationConfig extends WebMvcConfigurerAdapter {

	@Bean
	public PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer() {
		PropertyPlaceholderConfigurer placeholderConfigurer = new PropertyPlaceholderConfigurer();
		placeholderConfigurer.setLocation(new ClassPathResource(
				"application.properties"));
		placeholderConfigurer.setIgnoreUnresolvablePlaceholders(true);
		return placeholderConfigurer;
	}

}

Now the code concept of spring solr come here, Spring Data Solr, part of the larger Spring Data family, provides easy configuration and access to Apache Solr Search Server from Spring applications. It offers both low-level and high-level abstractions for interacting with the store.

Derived queries and annotations for Solr specific functionallity allow easy integration into existing applications. So spring data has provided Repositories to deal with different operations of Spring.

/**
 * 
 */
package com.spark.solr.web.repository;

import org.springframework.data.solr.repository.SolrCrudRepository;

import com.spark.solr.web.model.Entity;

/**
 * @author Sony
 *
 */
public interface EntityRepository extends SolrCrudRepository<Entity, Integer>{

}

Now let us start with our service layer and its implementation followed by DAO and its Implementation classes.
EntityService.java

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

import java.util.List;

/**
 * @author Sony
 *
 */
public interface EntityService {
	public void saveDocument();
	public void saveDocument(Object object);
	public void saveDocument(List<Object> objects);
}

EntityServiceImpl.java

/**
 * 
 */
package com.spark.solr.web.service.impl;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.repository.support.SolrRepositoryFactory;
import org.springframework.stereotype.Service;

import com.spark.solr.web.dao.EntityDAO;
import com.spark.solr.web.model.Entity;
import com.spark.solr.web.repository.EntityRepository;
import com.spark.solr.web.service.EntityService;

/**
 * @author Sony
 *
 */
@Service(value = "entityServiceImpl")
public class EntityServiceImpl implements EntityService {

	@Autowired
	SolrTemplate solrTemplate;

	@Autowired
	EntityDAO entityDao;

	EntityRepository entityRepository;
	
	/* (non-Javadoc)
	 * @see com.spark.solr.web.service.EntityService#saveDocument(java.lang.Object)
	 */
	@Override
	public void saveDocument(Object object) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see com.spark.solr.web.service.EntityService#saveDocument(java.util.List)
	 */
	public void saveDocument(List<Object> objects) {
		// TODO Auto-generated method stub
	}
	
	/* (non-Javadoc)
	 * @see com.spark.solr.web.service.EntityService#saveDocument()
	 */
	@Override
	public void saveDocument() {
		getLogger().info("------------- Before fetching the details from database-----------");
		List<Map<String, Object>> values = entityDao.getDataFromDB();
		List<Entity> entities = new ArrayList<Entity>();
		
		for (Map<String, Object> map : values) {
			
			Entity entity = new Entity();
			
			entity.setEmployeeId(Integer.valueOf(map.get("EmployeeID").toString()));
			entity.setLastName(map.get("LastName").toString());
			entity.setFirstName(map.get("FirstName").toString());
			entity.setTitle(map.get("Title").toString());
			entity.setTitleOfCourtesy(map.get("TitleOfCourtesy").toString());
			entities.add(entity);
		}
		getLogger().info("------------- Before pushing documents to Solr server -----------");
		for (Entity entity : entities) {
			getEntityRepository().save(entity);
		}
		getLogger().info("------------- documents push to solr server done ! -----------");
	}
	
	/**
	 * @return
	 */
	public EntityRepository getEntityRepository(){
		return new SolrRepositoryFactory(solrTemplate.getSolrServer()).getRepository(EntityRepository.class);
	}

	public Logger getLogger(){
		return LoggerFactory.getLogger(EntityServiceImpl.class);
	}

}

EntityDAO.java

package com.spark.solr.web.dao;

import java.util.List;
import java.util.Map;


public interface EntityDAO {

	public List<Map<String, Object>> getDataFromDB();
}

EntityDAOImpl.java

/**
 * 
 */
package com.spark.solr.web.dao.impl;

import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.spark.solr.web.dao.EntityDAO;
import com.spark.solr.web.db.DBQueries;
import com.spark.solr.web.service.impl.EntityServiceImpl;

/**
 * @author Sony
 *
 */
@Repository(value="entityDao")
public class EntityDAOImpl implements EntityDAO {
	
	@Autowired
	private JdbcTemplate jdbcTemplate;

	/* (non-Javadoc)
	 * @see com.spark.solr.web.dao.EntityDAO#getDataFromDB()
	 */
	@Override
	public List<Map<String, Object>> getDataFromDB() {
		getLogger().info("----------- Querying database for the records -------------");
		getLogger().info("----------- sql query : "+DBQueries.GET_ALL_EMPLOYEES);
		List<Map<String, Object>> values = jdbcTemplate.queryForList(DBQueries.GET_ALL_EMPLOYEES);
		return values;
	}
	
	public Logger getLogger(){
		return LoggerFactory.getLogger(EntityDAOImpl.class);
	}

}

Now for making a better abstraction between the dao layer and the quires that are used in that layer i implemented a separate utility class as below.

/**
 * 
 */
package com.spark.solr.web.db;

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

	public static final String GET_ALL_EMPLOYEES = "select * from employee";
	
}

Finally our entity model looks as below.

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

import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.annotation.Id;

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

	@Id
	@Field(value="id")
	private int employeeId;
	@Field(value="lastName")
	private String lastName;
	@Field(value="firstName")
	private String firstName;
	@Field(value="title")
	private String title;
	@Field(value="titleOfCourtesy")
	private String titleOfCourtesy;

	/**
	 * @return the employeeId
	 */
	public int getEmployeeId() {
		return employeeId;
	}

	/**
	 * @param employeeId
	 *            the employeeId to set
	 */
	public void setEmployeeId(int employeeId) {
		this.employeeId = employeeId;
	}

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

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

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

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

	/**
	 * @return the title
	 */
	public String getTitle() {
		return title;
	}

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

	/**
	 * @return the titleOfCourtesy
	 */
	public String getTitleOfCourtesy() {
		return titleOfCourtesy;
	}

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

}

Now let us look at the resource files that i used in this project 1.application.properties and 2.log4j.properties
please put the below files in “scr/main/resources” folder of your maven project.
application.properties

solr.server.host=http://localhost:8983/solr

db.driverClass=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/test
db.username=root
db.password=root

log4j.properties

log4j.rootLogger = INFO, rollingFile

log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.File=D:/spring-solr-dev.log
log4j.appender.rollingFile.MaxFileSize=2MB
log4j.appender.rollingFile.MaxBackupIndex=2
log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=%p %t %c - %m%n

Note : please find the log file in d drive as i have given in log4j.properties file. please chage the drive location if you need.

Now we have done with the coding part, it is time for deployment, from cmd please navigate to location of project and issue the command as mvn clean install package this should build the project with all the required dependencies and final artifact would be spark-solr.war file.
now deploy this war file in apache tomcat under webapps directory and put the below url in your browser.
http://localhost:8080/spark-solr/solr/controller/load

Once we hit the url the controller calls the service layer and from service layer invoke dao layer to ftch the data from database abd returned back to service layer now in service layer we have the object od Solr repository and using that we push the data to solr.

After tha data is pushed we cah check tha data in solr using the solr admin page. as below
SolrAdmin

using my previous post we can pull the data from solr and show on custom UI.
Happy coding πŸ™‚ happy Solr πŸ™‚

Spring Data JPA to persist the domain objects

Hi all,These days i am taking little time to post new topics as i am doing little R&D in spring’s latest projects like ‘SpringBoot’ and ‘SpringData’. Now here is the post which will explain about ‘SpringData’. Please follow the code little carefully as i wrote block comments in order to better understand the logic. this project is designed under Maven,Spring4.1.1.RELEASE, Eclipse Luna and Tomcat 8.0.11.

Please find the below is the project structure, First let us start with required dependencies for the project as shown below.
project_structure
pom.xml

<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.data.rest</groupId>
	<artifactId>SpringDataRest</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>SpringDataRest</name>
	<description>SpringDataRest</description>
	
	<repositories>
		<repository>
			<id>repository.jboss.org-public</id>
			<name>JBoss repository</name>
			<url>https://repository.jboss.org/nexus/content/groups/public</url>
		</repository>
	</repositories>
	<properties>
		<hibernate.version>4.0.1.Final</hibernate.version>
		<mysql.connector.version>5.1.9</mysql.connector.version>
		<slf4j.version>1.6.1</slf4j.version>
		<spring.version>4.1.1.RELEASE</spring.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
		<!-- Spring Framework -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</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-jdbc</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-tx</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- Spring MVC -->
		<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>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>2.2.2</version>
		</dependency>
		<!-- Spring Data JPA -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-jpa</artifactId>
			<version>1.0.2.RELEASE</version>
		</dependency>
		<!-- Hibernate -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>4.0.1.GA</version>
		</dependency>

		<!-- H2 Database -->
		<!-- <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> 
			<version>1.3.160</version> </dependency> -->
		<!-- MySQL JDBC connector -->
		<!-- If you want to use MySQL, uncomment this dependency declation. -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.connector.version}</version>
		</dependency>
		<!-- PostgreSQL JDBC 4 -->
		<!-- If you don't want to use PostgreSQL, uncomment this dependency declaration. -->
		<!-- <dependency> <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> 
			<version>9.0-801.jdbc4</version> </dependency> -->
		<!-- BoneCP -->
		<dependency>
			<groupId>com.jolbox</groupId>
			<artifactId>bonecp</artifactId>
			<version>0.7.1.RELEASE</version>
		</dependency>
		<!-- Servlet API 3.0 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<!-- Logging dependencies -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.16</version>
		</dependency>
		<!-- Testing Dependencies -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.9</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<finalName>SpringData</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.1.1</version>
				<configuration>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Let us carry on with all the configurations required by the project and then with the actual logic. below is the code for the ‘application.properties’ file and ‘applicationContext.xml’
application.properties this file is fully loaded with all properties which are required by major databases, just uncomment what ever you need and use it.

# The default database is H2 memory database but I have also
# added configuration needed to use either MySQL and PostgreSQL.
 
#Database Configuration

#db.driver=org.h2.Driver
db.driver=com.mysql.jdbc.Driver
#db.driver=org.postgresql.Driver
#db.driver=oralce.jdbc.driver.OracleDriver

#db.url=jdbc:h2:mem:datajpa
db.url=jdbc:mysql://localhost:3306/test
#db.url=jdbc:postgresql://localhost/datajpa
#db.url=jdbc:oracle:thin:@localhost:1521:xe

db.username=?
db.password=?
 
#Hibernate Configuration
#hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.dialect=org.hibernate.dialect.MySQLDialect
#hibernate.dialect=org.hibernate.dialect.OracleDialect
#hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

hibernate.format_sql=true
hibernate.ejb.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy
hibernate.show_sql=true
 
#MessageSource
message.source.basename=i18n/messages
message.source.use.code.as.default.message=true
 
#EntityManager
#Declares the base package of the entity classes
entitymanager.packages.to.scan=com.spark.spring.data.domain

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
	
	<!-- Configures the location of static resources such as css files. Requires 
		Spring Framework 3.0 or higher. -->
	<mvc:resources mapping="/static/**" location="/static/" />

	<!-- Ensures that dispatcher servlet can be mapped to '/' and static resources 
		are still served by the containers default servlet. Requires Spring Framework 
		3.0 or higher. -->
	<mvc:default-servlet-handler />

	<!-- Configures Spring Data JPA and sets the base package of repositories. -->
	<jpa:repositories base-package="com.spark.spring.data.repositories" />

</beans>

Now it is time for us to write Java Configurations for Spring to initialize various bean objects and to recognize various annotations in the project, also let us write a configuration for servlet initialization instead of traditional web.xml

ApplicationConfig.java : this class is responsible for initialising the DataSource,JpaTransactionManager and for setting Hibernate properties

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

import java.util.Properties;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.hibernate.ejb.HibernatePersistence;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
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;

/**
 * An application context Java configuration class. The usage of Java configuration
 * requires Spring Framework 3.0 or higher with following exceptions:
 * <ul>
 *     <li>@EnableWebMvc annotation requires Spring Framework 3.1</li>
 * </ul>
 * @author Pavan Kumar Mantha
 */
@Configuration
@ComponentScan(basePackages = {"com.spark.spring.data"})
@EnableWebMvc
@ImportResource("classpath:applicationContext.xml")
@PropertySource("classpath:application.properties")
public class ApplicationConfig {

	private static final String VIEW_RESOLVER_PREFIX = "/WEB-INF/jsp/";
    private static final String VIEW_RESOLVER_SUFFIX = ".jsp";
 
    private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
    private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
    private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
    private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
 
    private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
    private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
    private static final String PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY = "hibernate.ejb.naming_strategy";
    private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
    private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
 
    @Resource
    private Environment environment;
    
    @Bean
    public DataSource getDataSource(){
    	DriverManagerDataSource dataSource = new DriverManagerDataSource();
    	dataSource.setDriverClassName(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
        dataSource.setUrl(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
        dataSource.setUsername(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
        dataSource.setPassword(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
 
        return dataSource;
    }
    
    @Bean(name="transactionManager")
    public JpaTransactionManager getJpaTransactionManager() throws ClassNotFoundException{
    	JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
    	jpaTransactionManager.setEntityManagerFactory(getLocalEntityManagerFactoryBean().getObject());
    	return jpaTransactionManager;
    }
    
    @Bean
    public LocalContainerEntityManagerFactoryBean getLocalEntityManagerFactoryBean(){
    	LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    	entityManagerFactoryBean.setDataSource(getDataSource());
    	entityManagerFactoryBean.setPackagesToScan(environment.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
    	entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistence.class);
    	
    	Properties properties = new Properties();
    	properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
    	properties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
    	properties.put(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY));
    	properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
    	
    	entityManagerFactoryBean.setJpaProperties(properties);
    	return entityManagerFactoryBean;
    }
    
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
 
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix(VIEW_RESOLVER_PREFIX);
        viewResolver.setSuffix(VIEW_RESOLVER_SUFFIX);
 
        return viewResolver;
    }
}

WebContextInit.java : This class is responsible for initializing the servlet(front controller) and remember this will only work with servlet 3 containers only.

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

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

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

/**
 * Web application Java configuration class. The usage of web application
 * initializer requires Spring Framework 3.1 and Servlet 3.0.
 * @author Pavan kumar Mantha
 */
public class WebContextInit implements WebApplicationInitializer {

	private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
	private static final String DISPATCHER_SERVLET_MAPPING = "/rest/*";

	@Override
	public void onStartup(ServletContext servletContext)
			throws ServletException {
		AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext();
		annotationConfigWebApplicationContext.register(ApplicationConfig.class);

		ServletRegistration.Dynamic dynamic = servletContext.addServlet(
				DISPATCHER_SERVLET_NAME, new DispatcherServlet(
						annotationConfigWebApplicationContext));
		dynamic.setLoadOnStartup(1);
		dynamic.addMapping(DISPATCHER_SERVLET_MAPPING);
		
	}

}

Now let us design our domain objects, data transfer objects and User defined Exceptions. In this case our domain object is “Person.java”. in this class we have a static inner class which is called “Builder”, the responsibility of Builder class is to create Person objects and return them.
Person.java

/**
 * 
 */
package com.spark.spring.data.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;

/**
 * An entity class which contains the information of a single person.
 * 
 * @author Pavan kumar Mantha
 */
@Entity
@Table(name = "person")
public class Person {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	@Column(name = "first_name", nullable = false)
	private String firstName;

	@Column(name = "last_name", nullable = false)
	private String lastName;

	@Version
	private long version = 0;

	/**
	 * @return the id
	 */
	public Long getId() {
		return id;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * @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 version
	 */
	public long getVersion() {
		return version;
	}

	/**
	 * @param version
	 *            the version to set
	 */
	public void setVersion(long version) {
		this.version = version;
	}
	
	/**
	 * this method returns the builder object
	 */
	public static Builder getBuilder(String firstName,String lastName){
		return new Builder(firstName, lastName);
	}
	
	/**
	 * A Builder class that is used to create Person Object.
	 */
	public static class Builder{
		
		Person person;
		
		public Builder(String firstName, String lastName) {
			person = new Person();
			person.firstName = firstName;
			person.lastName = lastName;
		}
		
		public Person build(){
			return person;
		}
	}

}

PersonDTO.java : This class is responsible to inject the data from the front end and then push that to builder class and get the original person domain object

/**
 * 
 */
package com.spark.spring.data.domain;

import org.hibernate.validator.constraints.NotEmpty;

/**
 * A DTO object which is used as a form object
 * in create person and edit person forms.
 * @author Pavan Kumar Mantha
 */
public class PersonDTO {

	private Long id;

	@NotEmpty
	private String firstName;

	@NotEmpty
	private String lastName;

	public PersonDTO() {

	}

	public Long getId() {
		return id;
	}

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

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

}

PersonNotFoundException.java

/**
 * 
 */
package com.spark.spring.data.exceptions;

/**
 * @author Pavan Kumar mantha
 *
 */
public class PersonNotFoundException extends Exception{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public PersonNotFoundException() {
		super();
	}
	
	@Override
	public synchronized Throwable getCause() {
		return super.getCause();
	}
	
	@Override
	public String getMessage() {
		return super.getMessage();
	}
}

Since all our Domain Objects,DTO objects and custom exception types are in place, its time for us to write our Repository Interface. Spring Data has given an out of the box functionality for CRUD operations called CRUDRepository and there are many other Repositories which will extend from this base interface and one of them is “JpaRepository”. It is prety straight forward to design a repository all you have to do is to create an interface which extends the JpaRepository interface. The JpaRepository interface is a JPA specific extension to the Repository interface and it gives you the access to following methods which are used to implement the CRUD application:

delete(T entity) which deletes the entity given as a parameter.
findAll() which returns a list of entities.
findOne(ID id) which returns the entity using the id given a parameter as a search criteria.
save(T entity) which saves the entity given as a parameter.

PersonRepository.java

/**
 * 
 */
package com.spark.spring.data.repositories;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.spark.spring.data.domain.Person;

/**
 * Specifies methods used to obtain and modify person related information
 * which is stored in the database.
 * @author Pavan Kumar Mantha
 */
@Transactional(value="transactionManager",propagation=Propagation.NESTED)
public interface PersonRepository extends JpaRepository<Person, Long>{

}

Once we have our PersonRepository interface ready to use, let us start with service layer to hadle the business logic.
PersonService.java : This interface is responsible for basic operations on the domain object in connection with the underlying database.

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

import java.util.List;

import com.spark.spring.data.domain.Person;
import com.spark.spring.data.domain.PersonDTO;
import com.spark.spring.data.exceptions.PersonNotFoundException;

/**
 * Declares methods used to obtain and modify person information.
 * @author Pavan Kumar Mantha
 */
public interface PersonService {

	/**
     * Creates a new person.
     * @param created   The information of the created person.
     * @return  The created person.
     */
    public Person create(PersonDTO personDTO);
 
    /**
     * Deletes a person.
     * @param personId  The id of the deleted person.
     * @return  The deleted person.
     * @throws PersonNotFoundException  if no person is found with the given id.
     */
    public Person delete(Long personId) throws PersonNotFoundException;
 
    /**
     * Finds all persons.
     * @return  A list of persons.
     */
    public List<Person> findAll();
 
    /**
     * Finds person by id.
     * @param id    The id of the wanted person.
     * @return  The found person. If no person is found, this method returns null.
     */
    public Person findById(Long id);
 
    /**
     * Updates the information of a person.
     * @param updated   The information of the updated person.
     * @return  The updated person.
     * @throws PersonNotFoundException  if no person is found with given id.
     */
    public Person update(PersonDTO personDTO) throws PersonNotFoundException;
}

The implmentation for the above service interface is as below.
Note : all the methods of interface are implemented with default definition and only create has the exact logic, the others are left for you people to implement.Also observer @Transactional annotation it is at the method level not at the class level.
Please observer that the PersonRepository class gets injected by the spring container and CRUD operation capability is provided by it.
PersonServiceImpl.java

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

import java.util.List;

import javax.annotation.Resource;

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

import com.spark.spring.data.domain.Person;
import com.spark.spring.data.domain.PersonDTO;
import com.spark.spring.data.exceptions.PersonNotFoundException;
import com.spark.spring.data.repositories.PersonRepository;
import com.spark.spring.data.service.PersonService;

/**
 * This implementation of the PersonService interface communicates with
 * the database by using a Spring Data JPA repository.
 * @author Pavan Kumar Mantha
 */
@Service(value="personService")
public class PersonServiceImpl implements PersonService{

	@Resource
	private PersonRepository personRepository;
	
	@Override
	@Transactional(value="transactionManager")
	public Person create(PersonDTO personDTO) {

		Person person = Person.getBuilder(personDTO.getFirstName(), personDTO.getLastName()).build();
		return personRepository.save(person);
	}

	@Override
	public Person delete(Long personId) throws PersonNotFoundException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Person> findAll() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Person findById(Long id) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Person update(PersonDTO personDTO) throws PersonNotFoundException {
		// TODO Auto-generated method stub
		return null;
	}

}

Now every thing is completed from logic point of view let us start with the controller class class to handle different request from client.
Please observe that i have hard coded the values from domain object here, in my next post i will be making this as dynamic, for time being this is for testing.

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

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 com.spark.spring.data.domain.PersonDTO;
import com.spark.spring.data.service.PersonService;

/**
 * @author Pavan Kumar Mantha
 *
 */
@Controller
public class ApplicationController {

	@Autowired
	private PersonService personService;
	
	@RequestMapping(value="/create",method=RequestMethod.GET)
	public void create(){
		System.out.println("-------------------inside the method-----------------"+personService);
		PersonDTO personDTO = new PersonDTO();
		personDTO.setFirstName("Pavan Kumar");
		personDTO.setLastName("Mantha");
		personService.create(personDTO);
	}
}

Thats it guys we are done with coding part, now build the project get the war file and deploy it to server.If you see no errors in server console please issue below request from browser “http://localhost:8080/SpringData/rest/create&#8221;.

in server you should see as below.
server_console

and when you query database that should look as below.
database_op

In my next post i will be integrating this project with AngularJs as my front end with fully Ajax driven application.

Happy Coding, Happy Spring Data πŸ™‚

Calling REST Services using Spring’s REST Template

Hi guys, here is my 80th blog post which talks about calling Restful service using Spring’s “RestTemplate”. This codebase is executed under Spring 3.1 and 4.0 dependencies. The project structure looks as shown below.
RestTemplate_proj_struct

let me explain one scenario here, the calling REST service can return JSON Object or an XML Document back to consumer. it si up to the implementation how to convert JSON back to Java Object or convert Xml Back to Java.
We have many Marshallers and UnMarshallers available some of them are Jaxb2Marshaller,Jibx Marshaller, XStreamMarshaller,XmlBeanMarshaller..etc, i personally used Jaxb2Marshaller in this project. let us now dive into the code, there is no much explanation needed in the code, please follow the comments over the code blocks.

ConfigUtil.java

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

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

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.xml.MarshallingHttpMessageConverter;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.web.client.RestTemplate;

import com.spark.spring.rest.models.Customer;

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

	/**
	 * @return the RetTemplate Object. This method sets the marshaller object as
	 *         params to RestTemplate leveraging the marshalling capability to
	 *         the template.
	 */
	@Bean(name = "restTemplate")
	public RestTemplate getRestTemplate() {
		RestTemplate restTemplate = new RestTemplate();

		List<HttpMessageConverter<?>> converters = new ArrayList<>();
		converters.add(getMarshallingHttpMessageConverter());
		converters.add(new FormHttpMessageConverter());
		converters.add(new StringHttpMessageConverter());
		restTemplate.setMessageConverters(converters);
		return restTemplate;
	}

	/**
	 * @return MarshallingHttpMessageConverter object which is responsible for
	 *         marshalling and unMarshalling process
	 */
	@Bean(name = "marshallingHttpMessageConverter")
	public MarshallingHttpMessageConverter getMarshallingHttpMessageConverter() {

		MarshallingHttpMessageConverter marshallingHttpMessageConverter = new MarshallingHttpMessageConverter();
		marshallingHttpMessageConverter.setMarshaller(getJaxb2Marshaller());
		marshallingHttpMessageConverter.setUnmarshaller(getJaxb2Marshaller());
		return marshallingHttpMessageConverter;
	}

	/**
	 * @return Jaxb2Marshaller, this is the Jaxb2Marshaller object
	 */
	@Bean(name = "jaxb2Marshaller")
	public Jaxb2Marshaller getJaxb2Marshaller() {
		Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
		jaxb2Marshaller.setClassesToBeBound(Customer.class);
		return jaxb2Marshaller;
	}
}

RestServiceConsumer .java, RestService call

/**
 * 
 */
package com.spark.spring.rest.consume;

import org.springframework.web.client.RestTemplate;

import com.spark.spring.rest.models.Customer;

/**
 * @author PavanKumar Mantha
 *
 */
public class RestServiceConsumer {

	/**
	 * @param restTemplate, this is the exact call to the service
	 */
	public static void consumeService(RestTemplate restTemplate){
		// getting xml directly from the response as string
		String xml = restTemplate.getForObject("http://www.thomas-bayer.com/sqlrest/CUSTOMER/18/", String.class);
		System.out.println(xml);
		
		// unmarshalling xml string to java object using Jaxb
		Customer customer = restTemplate.getForObject("http://www.thomas-bayer.com/sqlrest/CUSTOMER/18/", Customer.class);
		System.out.println(customer.getFirstName());
	}

}

Customer.java, Jaxb mapping POJO

/**
 * 
 */
package com.spark.spring.rest.models;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * @author PavanKumar Mantha
 * 
 */
@XmlRootElement(name="CUSTOMER")
public class Customer {

	private String id;
	private String firstName;
	private String lastName;
	private String street;
	private String city;

	/**
	 * @return the id
	 */
	@XmlElement(name="ID")
	public String getId() {
		return id;
	}

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

	/**
	 * @return the firstName
	 */
	@XmlElement(name="FIRSTNAME")
	public String getFirstName() {
		return firstName;
	}

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

	/**
	 * @return the lastName
	 */
	@XmlElement(name="LASTNAME")
	public String getLastName() {
		return lastName;
	}

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

	/**
	 * @return the street
	 */
	@XmlElement(name="STREET")
	public String getStreet() {
		return street;
	}

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

	/**
	 * @return the city
	 */
	@XmlElement(name="CITY")
	public String getCity() {
		return city;
	}

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

}

Main Method

/**
 * 
 */
package com.spark.spring.rest.test;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.web.client.RestTemplate;

import com.spark.spring.rest.config.ConfigUtil;
import com.spark.spring.rest.consume.RestServiceConsumer;

/**
 * @author PavanKumar Mantha
 *
 */
public class TestRestApp {

	/**
	 * @param args
	 */
	
	public static void main(String[] args) {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ConfigUtil.class);
		RestServiceConsumer.consumeService((RestTemplate)applicationContext.getBean("restTemplate"));
	}

}

finally when we run the main method you should see the below output on the screen.
console

Happy RESTing…(RestTemplate) πŸ™‚