Thursday, September 29, 2011

Spring ROO, An Amazing Framework

Recently I got an assignment to build a new web based server side project. Normally for Web based projects we used Spring MVC, Hibernate for persistence and Maven for dependencies management. At this point I have two options.

First option is to manually create a new Project, create Maven POM file, create folder structure, define dependencies related to spring and Hibernate, create Hibernate and Spring configuration files like persistence.xml and web.xml. Usually this process takes two to three hours to configure every thing properly and make this project in running condition

Second Option is to use “Spring Roo”. Spring Roo will work as my junior developer. It will automatically generate Application Structure, pom file, required configuration files for spring and hibernate and all this process will take maximum 5 to 10 minutes and for this I just have to execute few commands.

Is it real or I am in my dreams J

Spring Roo is a dynamic, domain-driven development framework from SpringSource the makers of the Spring framework. Spring Roo uses standard Java and Spring, but during development time, the Spring Roo shell watches you work, helping out as possible and required. Think of Spring Roo as being the ultimate pair-programming buddy, or the most advanced code completion you’ve ever seen

As an example of this power, suppose you’re in the middle of editing a JPA entity in a Spring Roo project, and adding a field of interest—perhaps a name field to a Customer entity. As soon as you’ve finished typing out the field definition, Spring Roo automatically jumps in and adds a corresponding accessor and mutator pair for that field to a shadow class definition in the background. Similarly, it will implement a toString() definition (reflecting the fields added) if one does not already exist, and it will implement an equals() method following the same criteria.. If you update the field, the accessor and mutator are updated as well as the equals and toString methods. If you add an equals method to the JPA entity, the shadow definition is removed, delegating to your implementation instead. So, this shadow class definition is kept in sync, responding to your changes, but it does not get in your way. It defers to your will in all cases.

So, you get Java, but you don’t have to pay the cost of writing all that Java.

The Tooling

Latest Spring Roo Release can be downloaded from http://www.springsource.org/download

Once downloading will finish you will find a folder spring-roo-1.2.0.M1. If you go to bin folder you will find roo.bat. Once you click on this file a command console will open and from here you can control your project. 

Another simpler option is to use Spring Source Tool Suit IDE which has built-in support of Spring Roo and you don’t have to worry about any configuration. This ID is freely available at Spring Source website

It’s an Eclipse based IDE Just download this IDE and start your development

New Project

To start a new Project just click on FileàNewàSpring Roo Project

  






Enter name of the project. In my case I named it “CustomerManagementSystem”. Define top level java package which in my case is “com.eiconsulting.cms” and press finish.

This will automatically generate a project with Correct Maven based application structure, pom.xml file with correct dependencies of JUnit, the correct and latest versions of spring, AspectJ, logging, and the latest servlet APIs. 

You will notice a Roo.shell at bottom of your ide


This shell is your pair programmer. Here you will write all your commands

So let’s start the magic of Roo

In our project we are planning to use JPA and for this Hibernate as a JPA provider and My SQL as a database. Our pair programmer will help us to configure all this we just need to execute a simple command at Roo console

Actually I am not good in remembering commands, I remember it was some thing like “persist” so I just type persis and press CTRL+ SPACE, automatically “persistence setup” appears in my console after that I press CTRL+ SPACE again now I have two options to define provider and database. Finally I configured my command like this

persistence setup --provider HIBERNATE --database MYSQL

I pressed enter and Magic started

Roo has defined all Hibernate related dependencies in my POM. In META-INF folder persistence.xml automatically created with all MySQL related configuration details and now in a newly generated database.properties file I just have to define database url, username and password.

Now my My Project has full support of Spring and Hibernate with all required configuration files.

After this step my IDE started complaining about Maven Dependency

Missing artifact org.springframework.roo:org.springframework.roo.annotations:jar:1.1.4.RELEASE:provided
I searched about this at Internet and come up with a very simple solution

Open you pom file and replace Roo dependency

        <!-- ROO dependencies -->
        <dependency>
            <groupId>org.springframework.roo</groupId>
            <artifactId>org.springframework.roo.annotations</artifactId>
            <version>${roo.version}</version>
            <scope>provided</scope>
        </dependency>

With this

        <dependency>
            <groupId>org.springframework.roo</groupId>
            <artifactId>org.springframework.roo.annotations</artifactId>
            <version>1.0.2.RELEASE</version>
            <scope>compile</scope>
        </dependency>

Problem solved

Next step is to write my business logic. My initial thinking, “defiantly I have to write all my code by my self “, Luckily Spring Roo is helping me here as well

Because I am developing a CMS so my business requirement is to create a Customer Entity which has name and address field. To create an entity in Spring ROO simply type

entity --class  com.eiconsulting.beans.Customer

In response ROO will automatically generate package and class with name Customer. Also you have noticed that ROO has created couple of configuration files for this entity. These files are not part of our project and they are ROO internal use and we don’t have to bother about them.

Next step, we want to add name and address field. Following commands will perform this action

field string --fieldName name –notNull
field string --fieldName address --notNull
You will notice that ROO has generated few annotation is Customer class
@RooJavaBean
@RooToString
@RooEntity

This is for ROO Internal use to assist you during development If you simply don’t want Roo to even bother, simply remove the annotation from the Customer.java file and watch as Spring Roo removes the corresponding .aj file. If, later, you decide you that you were a bit hasty in dismissing its help, simply replace the annotation and Roo will obediently hop back into action again.

From this point you can move forward and start writing your business logic as per our requirements

As I mentioned earlier that we are planning to build MVC based project and we noticed that our project doesn’t contains folder structure for a Web based project, also for MVC based project we need a Customer Controller

Well very simple just execute following command and see the magic

controller scaffold --entity com.eiconsulting.beans.Customer --class com.eiconsulting.web.CustomerController

Automatically ROO will convert you project to a Web based project with Customer Controller with proper directory structure for a web based project

Also you will notice that ROO has create lots of images, css files and sample images

All these files are for your support. You can delete them or use them as per your requirements

Just build your project using your maven package command and it will generate a resultant war file. In our case it is CustomerManagementSystem-0.1.0.BUILD-SNAPSHOT.war. Deploy it in your favourite web server

You will notice a file with name log.roo. This file contains all commands which you have executed in ROO so far

To remove Roo from a project, you need to import the project into Eclipse or SpringSource Tool Suite. Once the project has been imported into Eclipse, right-click the project name in Package Explorer and select Refactor > Push-In Refactor. If this option is missing, ensure that you have a recent version of AJDT installed. After selecting the push-in refactor menu option, a list of all Roo inter-type declarations will be displayed. Simply click OK. AJDT will have now moved all of the Roo inter-type declarations into your standard .java files. The old *_Roo_*.aj files will have automatically been deleted. Complete Removal details are present at this URL http://static.springsource.org/spring-roo/reference/html/removing.html


Reference: Getting Started with ROO

Wednesday, September 28, 2011

Restful WebServices using Spring

In recent years, Representational State Transfer (REST) has emerged as a popular information-centric alternative to traditional SOAP-based web services. In Spring, REST support builds upon Spring MVC

The fundamentals of REST

Representational: REST resources can be represented in virtually any form, including XML, JavaScript Object Notation (JSON), or even HTML—whatever form best suits the consumer of those resources
State: when working with REST, we’re more concerned with the state of a resource than with the actions we can take against resources.
Transfer: REST involves transferring resource data, in some representational form, from one application to another.

REST is about transferring the state of resources—in whatever form is most appropriate from a server to a client (or vice versa).

Spring supports development of REST resources in the following ways:

  • Controllers can handle requests for all HTTP methods, including the four primary REST methods: GET, PUT, DELETE, and POST.
  • The new @PathVariable annotation enables controllers to handle requests for parameterized URLs (URLs that have variable input as part of their path).
  • The <form:form> JSP tag from Spring’s form-binding JSP tag library, along with the new HiddenHttpMethodFilter, make it possible to submit PUT and DELETE requests from HTML forms, even in browsers that don’t support those HTTP methods.
  • Resources can be represented in a variety of ways using Spring’s view and view resolvers, including new view implementations for rendering model data as XML, JSON, Atom, and RSS.
  • The representation best suited for the client can be chosen using the new ContentNegotiatingViewResolver
  • View-based rendering can be bypassed altogether using the new @ResponseBody annotation and various HttpMethodConverter implementations.
  • Similarly, the new @RequestBody annotation, along with HttpMethodConverter implementations, can convert inbound HTTP data into Java objects passed into a controller’s handler methods.

Spring MVC’s model for writing controller classes is extremely flexible. Almost any method with almost any signature can be annotated to handle a web request. But a side effect of such flexibility is that Spring MVC allows you to develop controllers that aren’t ideal in terms of RESTful resources. It’s too easy to write RESTless controllers.

Example of Spring MVC (Restless controller)

@Controller
@RequestMapping("/displaySpittle.htm")
public class DisplaySpittleController {

private final SpitterService spitterService;

@Inject
public DisplaySpittleController(SpitterService spitterService)
{
this.spitterService = spitterService;
}

@RequestMapping(method=RequestMethod.GET)
public String showSpittle(@RequestParam("id") long id, Model model)
{
 model.addAttribute(spitterService.getSpittleById(id));
 return "spittles/view";
}
 }

Take note of the @RequestMapping annotation at the class level. It says that this controller will handle requests for /displaySpittle.htm. That seems to imply that this controller is focused on the specific use case of displaying spittles (which is corroborated by the name of the class).

Nothing is terribly wrong with how DisplaySpittleController is written. But it isn’t a RESTful controller. It’s action-oriented and focused on a specific use case: displaying a Spittle object’s details in HTML form. Even the controller’s class name agrees.

Handling RESTful URLs URLs are one of the first things that most people think about when starting to work with REST.


is an example of Restless URL. This URL doesn’t locate or identify a resource. It demands that the server display a Spittle. The only part of the URL that identifies anything is the id query parameter. The base portion of the URL is verb-oriented. That is to say that it’s a RESTless URL


is an example of Restful URL. One thing that’s not clear about this URL is what it does. That’s because the URL doesn’t do any-thing. Rather, it identifies a resource. Instead of using a query parameter to identify the resource, the entire base URL identifies the resource. In fact, the new URL has no query parameters at all

To enable parameterized URL paths, Spring 3 introduced a new @PathVariable anno-tation. To see how this works, look at SpittleController, a new Spring MVC control- ler that takes a resource-oriented approach to handling requests for Spittles.

@Controller
@RequestMapping("/spittles")
public class SpittleController
{
private SpitterService spitterService;

@Inject
public SpittleController(SpitterService spitterService)
{
 this.spitterService = spitterService;
}

 @RequestMapping(value="/{id}", method=RequestMethod.GET)
 public String getSpittle(@PathVariable("id") long id, Model model)
{
 model.addAttribute(spitterService.getSpittleById(id));
return "spittles/view";
}
 }

You’re probably wondering about those weird curly-braces in the URL pattern. The part that says {id} is a placeholder through which variable data will be pass into the method. It corresponds to the @PathVariable annotation on the id method parameter.



Restful Code Example

Following is Code for a Customer Controller. In this Code I tried to implement all CUID methods for Customer Object

package com.playground.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.playground.entity.Customer;
import com.playground.services.CustomerService;
@Controller

public class CustomerController {
            @Autowired @Qualifier("CustomerService")
            CustomerService service;
           
            @RequestMapping(value= "/findcustomer/{customerId}/",method={RequestMethod.GET})
            @ResponseStatus(HttpStatus.OK)
            public @ResponseBody String findCustomer(@PathVariable String customerId){
                        Customer c=service.findCustomer(customerId);
                        return "Here is Customer:"+c.getName();
            }
           
            @RequestMapping(value= "/savecustomers",method={RequestMethod.POST})
            @ResponseStatus(HttpStatus.CREATED)
            public @ResponseBody  String saveCustomer(@RequestParam(value="name") String name, @RequestParam(value="address", required=false) String address, @RequestParam(value="telephone") String telephone){
                         Customer c=new Customer();
                         c.setName(name);
                         c.setAddress(address);
                         c.setTelephone(telephone);
                         boolean result=service.saveCustomer(c);
                         if(result)
                                                return "Save Operation Completed Sucessfully";
                                    else
                                                return "Save Operation is not Sucessfull";
            }
           
            @RequestMapping(value= "/updatecustomers/{customerId}/{name}/{address}/{telephone}",method={RequestMethod.PUT})
            @ResponseStatus(HttpStatus.ACCEPTED)
            public  @ResponseBody String updateCustomerDetails(@PathVariable String customerId,@PathVariable String name, @PathVariable String address, @PathVariable String telephone){
                       
                        System.out.println("Here is the Customer Details:"+customerId+":"+name+":"+address+":"+telephone);
                         Customer c=new Customer();
                         c.setCustomerId(customerId);
                         c.setName(name);
                         c.setAddress(address);
                         c.setTelephone(telephone);
                         boolean result=service.updateCustomerDetails(c);
                         if(result)
                                                return "Update Operation Completed Sucessfully";
                                    else
                                                return "Update Operation is not Sucessfull";
            }
           
            @RequestMapping(value= "/deletecustomers/{customerId}",method={RequestMethod.DELETE})
            @ResponseStatus(HttpStatus.ACCEPTED)
            public  @ResponseBody String deleteCustomer(@PathVariable String customerId){
                                    System.out.println("Here is the Customer Id:"+customerId);
                                    boolean result=service.deleteCustomer(customerId);
                                    if(result)
                                                return "Delete Operation Completed Sucessfully";
                                    else
                                                return "Delete Operation is not Sucessfull";
            }
           
            @RequestMapping(value= "/allcustomers/",method={RequestMethod.GET})
            @ResponseStatus(HttpStatus.OK)
            public  @ResponseBody String getAllCustomers(){
                        List result=service.getAllCustomers();
                        return "Here is the list";
            }
           
}


URL for Find Customer

URL to Get All Customers

For Save Customer I have created a HTML form
Normal browsers doesn’t support PUT and DELETE HTTP method so I have created AJAX form to perform update and delete Operations

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Test Restful PlayGround</title>
   <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript">
            $(document).ready(function() {
                  //if submit button is clicked
                  $('#submit').click(function () {         
                        var customerId= $('input[name=customerId]');
                        //start the ajax
                        $.ajax({
                              //this is the php file that processes the data and send mail
                              url: "/RestfulPlayGround/deletecustomers/"+customerId.val(),     
                              type: "DELETE",
                              success: function (html) {                     
                                    alert(html);                 
                              }          
                        });
                        return false;
                  });  
                  $('#update').click(function () {         
                        //Get the data from all the fields
                        var customerId= $('input[name=customerId]');
                        var name= $('input[name=name]');
                        var address= $('input[name=address]');
                        var telephone= $('input[name=telephone]');
                       
                        //start the ajax
                        $.ajax({
                              //this is the php file that processes the data and send mail
                              url: "/RestfulPlayGround/updatecustomers/"+customerId.val()+"/"+name.val()+"/"+address.val()+"/"+telephone.val(),  
                              type: "PUT",
                              success: function (html) {                     
                                    alert(html);                 
                              }          
                        });
                        return false;
                  });  

            });  
    </script>
</head>
<body>
<br>
Delete Customer

<form  method="post">
<br>
Customer Id:<input type="text" name="customerId"><br>
<input type="submit" value="Submit" id="submit"/>
</form>


<br>
Update Customer
<form method="post">
<br>
Customer Id:<input type="text" name="customerId"><br>
Name:<input type="text" name="name"><br>
Address:<input type="text" name="address"><br>
Telephone:<input type="text" name="telephone"><br>
<input type="submit" id="update" value="Update">
</form>
<br>
Save Customer
<form method="POST" action="/RestfulPlayGround/savecustomers">
<br>
Name:<input type="text" name="name"><br>
Address:<input type="text" name="address"><br>
Telephone:<input type="text" name="telephone"><br>
<input type="submit" value="Save" id="save">
</form>

</body>
</html>

Complete Application Source Code is Present at following location
https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0B0YFdqXJcI3mYzM5ZDg0OTQtOTI1MS00YjBiLThhNjQtMTU1MTFmOWRlYjc2&hl=en

Reference: Spring in Action 3