Step by Step Guide to create a sample CRUD Java application using MongoDB and Spring Data for MongoDB.

MongoDB is a scalable, high-performance, open source NoSQL database. Instead of storing data in tables as is done in a “classical” relational database, it stores structured data as JSON-like documents with dynamic schemas. This post contains steps to create a sample application using MongoDB and Spring Data for MongoDB.

Spring Data for MongoDB

‘Spring data for MongoDB’ is providing a familiar Spring-based programming model for NoSQL data stores. It provides many features to the Java developers and make their life more simpler while working with MongoDB. MongoTemplate helper class support increases productivity performing common Mongo operations. Includes integrated object mapping between documents and POJOs.  As usual it translates exception into Spring’s portable Data Access Exception hierarchy.  The Java based Query, Criteria, and Update DSLs  are very useful to code all in Java. It also provides a cross-store persistence – support for JPA Entities with fields transparently persisted/retrieved using MongoDB.

You can download it from here: Download

Installing Mongo DB in just 5 steps!

There is no other place on internet which explains more clearly than its official installation reference. Following are the steps which I followed when I did its installation.

1. Download the latest production release of MongoDB from the MongoDB downloads page.

2. Unzip it into any of your convenient location say like

C:\MongoDB.

3. MongoDB requires a data folder to store its files. The default location for the MongoDB data directory is C:\data\db. But we can create any folder location for storing data. I want to make it in the same MongoDB folder. So I have created a folder at the below path.

C:\mongodb\data\db

4. That’s it! Go to C:\mongodb\bin folder and run mongod.exe with the data path

C:\mongodb\bin\mongod.exe –dbpath C:\mongodb\data\db

If your path includes spaces, enclose the entire path in double quotations, for example:

C:\mongodb\bin\mongod.exe –dbpath “C:\mongodb\data\db storage place”

image

5. To start MongoDB, go to its bin folder and run mongo.exe. This mongo shell will connect to the database running on the localhost interface and port 27017 by default. If you want to run MongoDB as a windows service then please see it here.

C:\mongodb\bin\mongod.exe

image

Okay, this part is done. Let it run there. Now we can create a small Java application with Spring Data.

Creating an application with Spring Data (Another 5 more steps!)

We need below Jars for creating this sample project. As I am a nature lover and a GoGreen person I named the project as “NatureStore”! Using this we are going to “Save” some “Trees” in to the DB!

Step1: Create a simple domain object.

The @Document annotation identifies a domain object that is going to be persisted to MongoDB.  And the  @Id annotation identifies its id.

package com.orangeslate.naturestore.domain;

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

@Document
public class Tree {

	@Id
	private String id;

	private String name;

	private String category;

	private int age;

	public Tree(String id, String name, int age) {
		this.id = id;
		this.name = name;
		this.age = age;
	}

	public String getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

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

	public String getCategory() {
		return category;
	}

	public void setCategory(String category) {
		this.category = category;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", age=" + age
				+ ", category=" + category + "]";
	}
}

Step2: Create a simple Interface.

Created a simple interface with CRUD methods. I have also includes createColletions and dropCollections into this same interface.

package com.orangeslate.naturestore.repository;

import java.util.List;

import com.mongodb.WriteResult;

public interface Repository<T> {

	public List<T> getAllObjects();

	public void saveObject(T object);

	public T getObject(String id);

	public WriteResult updateObject(String id, String name);

	public void deleteObject(String id);

	public void createCollection();

	public void dropCollection();
}

Step 3: Create an implementation class specifically for Tree domain object. It also initializes the MongoDB Collections.

package com.orangeslate.naturestore.repository;

import java.util.List;

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.mongodb.WriteResult;
import com.orangeslate.naturestore.domain.Tree;

public class NatureRepositoryImpl implements Repository<Tree> {

	MongoTemplate mongoTemplate;

	public void setMongoTemplate(MongoTemplate mongoTemplate) {
		this.mongoTemplate = mongoTemplate;
	}

	/**
	 * Get all trees.
	 */
	public List<Tree> getAllObjects() {
		return mongoTemplate.findAll(Tree.class);
	}

	/**
	 * Saves a {@link Tree}.
	 */
	public void saveObject(Tree tree) {
		mongoTemplate.insert(tree);
	}

	/**
	 * Gets a {@link Tree} for a particular id.
	 */
	public Tree getObject(String id) {
		return mongoTemplate.findOne(new Query(Criteria.where("id").is(id)),
				Tree.class);
	}

	/**
	 * Updates a {@link Tree} name for a particular id.
	 */
	public WriteResult updateObject(String id, String name) {
		return mongoTemplate.updateFirst(
				new Query(Criteria.where("id").is(id)),
				Update.update("name", name), Tree.class);
	}

	/**
	 * Delete a {@link Tree} for a particular id.
	 */
	public void deleteObject(String id) {
		mongoTemplate
				.remove(new Query(Criteria.where("id").is(id)), Tree.class);
	}

	/**
	 * Create a {@link Tree} collection if the collection does not already
	 * exists
	 */
	public void createCollection() {
		if (!mongoTemplate.collectionExists(Tree.class)) {
			mongoTemplate.createCollection(Tree.class);
		}
	}

	/**
	 * Drops the {@link Tree} collection if the collection does already exists
	 */
	public void dropCollection() {
		if (mongoTemplate.collectionExists(Tree.class)) {
			mongoTemplate.dropCollection(Tree.class);
		}
	}
}

Step 4: Creating Spring context.

Declare all the spring beans and mongodb objects in Spring context file. Lets call it as applicationContext.xml. Note we are creating not created a database with name “nature” yet. MongoDB will create it once we saves our first data.

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

	<bean id="natureRepository"
		class="com.orangeslate.naturestore.repository.NatureRepositoryImpl">
		<property name="mongoTemplate" ref="mongoTemplate" />
	</bean>

	<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
		<constructor-arg name="mongo" ref="mongo" />
		<constructor-arg name="databaseName" value="nature" />
	</bean>

	<!-- Factory bean that creates the Mongo instance -->
	<bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean">
		<property name="host" value="localhost" />
		<property name="port" value="27017" />
	</bean>

	<!-- Activate annotation configured components -->
	<context:annotation-config />

	<!-- Scan components for annotations within the configured package -->
	<context:component-scan base-package="com.orangeslate.naturestore">
		<context:exclude-filter type="annotation"
			expression="org.springframework.context.annotation.Configuration" />
	</context:component-scan>

</beans>

Step 5: Creating a Test class

Here I have created a simple test class and initializing context inside using ClassPathXmlApplicationContext.

package com.orangeslate.naturestore.test;

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

import com.orangeslate.naturestore.domain.Tree;
import com.orangeslate.naturestore.repository.NatureRepositoryImpl;
import com.orangeslate.naturestore.repository.Repository;

public class MongoTest {

	public static void main(String[] args) {

		ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
				"classpath:/spring/applicationContext.xml");

		Repository repository = context.getBean(NatureRepositoryImpl.class);

		// cleanup collection before insertion
		repository.dropCollection();

		// create collection
		repository.createCollection();

		repository.saveObject(new Tree("1", "Apple Tree", 10));

		System.out.println("1. " + repository.getAllObjects());

		repository.saveObject(new Tree("2", "Orange Tree", 3));

		System.out.println("2. " + repository.getAllObjects());

		System.out.println("Tree with id 1" + repository.getObject("1"));

		repository.updateObject("1", "Peach Tree");

		System.out.println("3. " + repository.getAllObjects());

		repository.deleteObject("2");

		System.out.println("4. " + repository.getAllObjects());
	}
}

Lets run it as Java application. We can see the below output. First method saves “Apple Tree” into the database. Second method saves “OrangeTree” also into the database. Third method demonstrates finding an object with its id. Fourth one updates an existing object name with “Peach Tree”. And at last; the last method deletes the second object from DB.

1. [Person [id=1, name=Apple Tree, age=10, category=null]]
2. [Person [id=1, name=Apple Tree, age=10, category=null], Person [id=2, name=Orange Tree, age=3, category=null]]
Tree with id 1Person [id=1, name=Apple Tree, age=10, category=null]
3. [Person [id=1, name=Peach Tree, age=10, category=null], Person [id=2, name=Orange Tree, age=3, category=null]]
4. [Person [id=1, name=Peach Tree, age=10, category=null]]

NOTE: You can download all this code from Github!

Advertisements

Creating Web Services using CXF (Contract first Approach) Part 2 : WSDL Creation.

What is WSDL and what its Structure?

A WSDL document defines services as collections of network endpoints, or ports. In WSDL, the abstract definition of endpoints and messages is separated from their concrete network deployment or data format bindings. This allows the reuse of abstract definitions: messages, which are abstract descriptions of the data being exchanged, and port types which are abstract collections of operations.

The concrete protocol and data format specifications for a particular port type constitutes a reusable binding. A port is defined by associating a network address with a reusable binding, and a collection of ports define a service. Hence, a WSDL document uses the following elements in the definition of network services:

WSDL document describes a web service using these major elements:

Element Defines
<types> The data types used by the web service
<message> The messages used by the web service
<portType> The operations performed by the web service
<binding> The communication protocols used by the web service
<port> A single endpoint defined as a combination of a binding and a network address.
<service> A collection of related endpoints.

The main structure of a WSDL document looks like this:

<definitions>
<types>
definition of types……..
</types>

<message>
definition of a message….
</message>
             <portType>
definition of a port…….
</portType>
           
<binding>
definition of a binding….
</binding>

              <service>
definition of services….
</service>

</definitions>

A WSDL document can also contain other elements, like extension elements and a service element that makes it possible to group together the definitions of several web services in one single WSDL document.

Creating WSDL for our Example

<types>:In the Types we are defining or configuring the Datatypes which we are using for the entire application. Here we are importing the XSD files here.

<message>:In our example we need to configure our input and our parameters/ the message which we are passing through Webservice. We are configuring request and response objects here.

<portType>: We have one operation which is called getProduct. So here we need to declare this getProduct operation.

<binding> : Here we will be providing our protocol types and we are using SOAP protocol.

<service> : Defining the Service End point. And for the ProductService we are defining it as “http://localhost:8080/ContractFirst/services/ProductService

 

   1: <?xml version="1.0" encoding="UTF-8" standalone="no"?>
   2: <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
   3:     xmlns:tns="http://com/your/company/service/ProductService/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
   4:     xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ProductService"
   5:     targetNamespace="http://com/your/company/service/ProductService/"
   6:     xmlns:prd="http://com/your/company/service/Product/">
   7:     <wsdl:types>
   8:         <xsd:schema targetNamespace="http://com/your/company/service/ProductService/"
   9:             xmlns:prd="http://com/your/company/service/Product/">
  10:             <xsd:import namespace="http://com/your/company/service/Product/"
  11:                 schemaLocation="../Product.xsd" />
  12:             <xsd:element name="getProductRequest">
  13:                 <xsd:complexType>
  14:                     <xsd:sequence>
  15:                         <xsd:element name="productRequest" type="prd:ProductRequest" />
  16:                     </xsd:sequence>
  17:                 </xsd:complexType>
  18:             </xsd:element>
  19:             <xsd:element name="getProductResponse">
  20:                 <xsd:complexType>
  21:                     <xsd:sequence>
  22:                         <xsd:element name="productResponse" type="prd:ProductResponse" />
  23:                     </xsd:sequence>
  24:                 </xsd:complexType>
  25:             </xsd:element>
  26:         </xsd:schema>
  27:     </wsdl:types>
  28:     <wsdl:message name="ProductRequest">
  29:         <wsdl:part element="tns:getProductRequest" name="parameters" />
  30:     </wsdl:message>
  31:     <wsdl:message name="ProductResponse">
  32:         <wsdl:part element="tns:getProductResponse" name="parameters" />
  33:     </wsdl:message>
  34:     <wsdl:portType name="ProductService">
  35:         <wsdl:operation name="getProduct">
  36:             <wsdl:input message="tns:ProductRequest" />
  37:             <wsdl:output message="tns:ProductResponse" />
  38:         </wsdl:operation>
  39:     </wsdl:portType>
  40:     <wsdl:binding name="ProductServiceSOAP" type="tns:ProductService">
  41:         <soap:binding style="document"
  42:             transport="http://schemas.xmlsoap.org/soap/http" />
  43:         <wsdl:operation name="getProduct">
  44:             <soap:operation
  45:                 soapAction="http://com/your/company/service/ProductService/getProduct" />
  46:             <wsdl:input>
  47:                 <soap:body use="literal" />
  48:             </wsdl:input>
  49:             <wsdl:output>
  50:                 <soap:body use="literal" />
  51:             </wsdl:output>
  52:         </wsdl:operation>
  53:     </wsdl:binding>
  54:     <wsdl:service name="ProductService">
  55:         <wsdl:port binding="tns:ProductServiceSOAP" name="ProductServiceSOAP">
  56:             <soap:address
  57:                 location="http://localhost:8080/ContractFirst/services/ProductService" />
  58:         </wsdl:port>
  59:     </wsdl:service>
  60: </wsdl:definitions>

In our next part we will go through Skelton creation using WSDL to Java tool which is giving by CXF. We will go through class path settings and wsdl2java commands.

Creating Web services using Apache CXF (Part 1) : The Basics.

As we discussed in the previous post, CXF is the combination of two projects: Celtix developed by IONA and XFire developed by Codehaus working together at the Apache Software Foundation.

 

 

Apache CXF- An ultimate web service open source framework : Lets start learning…

Apache CXF is an open source services framework which is a result of the merge between the XFire and Celtix projects. CXF helps us build and develop services using JAX-WS. These services can speak a variety of protocols such as SOAP, XML/HTTP, RESTful HTTP, or CORBA and work over a variety of transports such as HTTP, JMS or JBI.

In this series we will go through two common approaches to create a web service.

  1. Code first approach
  2. Contract First approach