Pages

Friday, November 7, 2014

Spring Boot examples

What is spring boot?


There are probably a lot of explanations about what it is, but my take on it is simple:
Spring Boot solves your classpath problems without troubling you thinking about it.

For example: Let's say you want to build a standard Spring MVC application.
You create a maven project (or gradle), you add spring-web to classpath and you get it working.
You may be missing few jars so you simple add it to your pom.xml

With Spring Boot, you don't need to do so. Once you add a class and annotate it with @RestController, Spring will automatically add all the jars to the classpath that Spring thinks you need.
It may be more than you really need, but this is an opinionated view - take it or leave it.

Interesting features

For me, the most interesting feature besides classpath resolution is an ability to run Spring Boot application as simple java app, even if it is intended to be a web server. 
Spring Boot apps are intended to be run as java apps (jar files). Once you have some web semantics in your application (lets say you added a Controller) then Spring Boot will realize that and start embedded Tomcat and will let you use your application without creating a WAR file and deploying it into some Tomcat.

Examples

Very Basic Application

If you are user of STS (Spring Tools Suite) then you can simply create a basic Spring App.
Click on File -> New -> Spring Started Project and you will see this:
Once you created such application, you can simply run it as Java Application. It would not do much, but you can access Spring Context and see what are the default beans that are configured.

The class that would be generated in your project (Application) will have those lines:

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}


If you assign the return value of "run" to ApplicationContext then you can access all your beans.

Basic Application

The more interesting behavior will happen if you add a class to your project and annotate it as @RestController and rerun your application as Java Application.
What will happen is that Spring will start a tomcat instance and will not shutdown as in the first example, until you explicitly shut it down.

So if you will add a code:

@RestController 
public class ProductVerionController { 
 @RequestMapping("/version") 
 public String getVersion() { 
    return "1.0.0"; 
 } 
}



Then once the application is started, you can browse to http://localhost:8080/version and see the response "1.0.0"
There are few interesting points about this behavior:

  1. You run the program as simple Java but it is run as a web server (with embedded tomcat)
  2. There is not "web application name" in the URL, it is as if you deployed it to the ROOT of your tomcat - that aligns well with how Pivotal CloudFoundry deploys java apps and confirms that Spring Boot may be the way for building and deploying CF apps in the future

Basic Application + Some HTML files

By now, you have a simple web server that returns one String. 
But what if you need some html files? some static resources? at the end of the day, you have a web app.
Luckily, Spring Boot makes this easy as well. If you recall, in Spring MVC you had this line configured in servlet context

<resources location="/resources/" mapping="/resources/**" >

Well, this line was essentially taking resources from classpath of your web server.
In the case of Spring Boot, you don't have a web server, but you have a simple java application.
What you need to do in this case is something very simple.
Add either a folder named "resources" or "static" into src/main/resources folder, and any static HTML that you have there will be served by your app.
Here is my project structure:

and if you run an application than the URLs
http://localhost:8080/resources.html
and
http://localhost:8080/static.html
will return the respective HTML pages that I placed in a predefined folders I created

Next time - WAR files with Spring Boot.

Monday, January 27, 2014

Configuring Spring MVC with Mongo DB

Mongo DB is a popular NoSql database, that stores JSON objects.
It has few concepts to be aware of:
1. Collections - an equivalent of table in relational database
2. Document - an equivalent of a row in a table.
As a result, one can create collections and store documents inside them

Unlike relational database, structure of documents in the collection does not have to be identical.
It is common practice to have a similar structure, but it is not necessary the case

Now lets build a sample application with Mongo DB.
It will have one domain class BasicPerson and one service class PersistenceServiceImpl

Code for BasicPerson (setters and getters omitted ):
public class BasicPerson {
    private String id = null;
    private String name = null;
    private String lastName = null;
}


Code for PersistenceServiceImpl(interface declaration omitted ):
package com.dimalimonov.restmongo.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.stereotype.Service;
import com.dimalimonov.restmongo.domain.BasicPerson;

@Service
public class PersistenceServiceImpl implements PersistenceService {

    private static final String COLLECTION_NAME="restperson";

    @Autowired
    private MongoOperations mongoOperations = null;

    @Override
    public BasicPerson save(BasicPerson bp) {
        mongoOperations.insert(bp, COLLECTION_NAME);
    return bp;
    }

    @Override
    public List find() {
       List users = mongoOperations.findAll(BasicPerson.class, COLLECTION_NAME);
    return users;
    }

    @Override
    public BasicPerson update(BasicPerson bp) {
        mongoOperations.save(bp, COLLECTION_NAME);
    return bp;
    }
}

XML Configuration for the system:
<?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:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd">

<mongo:mongo id="mongoDefault" host="127.0.0.1" port="27017" />

<mongo:db-factory id="mongoDbFactory" dbname="rest" mongo-ref="mongoDefault" />

<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" /> </beans>

Explanation

What is happening here, is rather simple, if you are familiar with Spring Template mechanism
First, you create a Mongo bean. This bean represents an instance of the database server you run, so you supply it host and port
Secondly, you create a Mongo Factory instance, where you reference a database in the Mongo server. This database will be used by you to create collections and documents in
Lastly, you create a Mongo template using the factory. Template will allow you to execute calls on the db.

When the mongoOperations.save(bp, COLLECTION_NAME); is invoked, Spring will serialize an instance of
BasicPerson into a JSON object (there is a default serializer for that) and will store it for you.
Other methods work similar using default deserialization
Interesting thing to notice is that when an object stored in Mongo, a special property _class will be stored with a class name for the object:
{
"_id": ObjectId("52e2b8ed8b4c2330d02d3ab8"),
"_class": "com.dimalimonov.restmongo.domain.BasicPerson",
"name": "newone",
"lastName": "newone1"
}