A Technology Blog About Code Development, Architecture, Operating System, Hardware, Tips and Tutorials for Developers.

Tuesday, December 25, 2012

@RequestParam - JAX-RS

11:38:00 PM Posted by Satish , , , , , , No comments
For this tutorial, I will be using the workspace created in my tutorial RESTful Web Service with Spring 3.1. So I suggest you to read RESTful Web Service with Spring 3.1, before start reading this tutorial. In JAX-RS, you can use @RequestParam annotation to inject URI query parameter into Java method and in this tutorial I will demonstrate how to use this using Spring 3.1.0.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.techiekernel.service;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.techiekernel.model.FooBar;
import com.techiekernel.model.FooBarSet;

/**
 * This exmaple has been created to demonstrate the @RequestParam for JAX-RS
 * 
 * @author satish
 * 
 */
@Controller
@RequestMapping("/foobaresample3")
public class FooBarServiceExample3 {

 static FooBarSet fooBarSet;

 static {
  fooBarSet = new FooBarSet();
  FooBar foobar = null;
  for (int i = 0; i < 10; i++) {
   foobar = new FooBar(i, "TechieKernel" + i);
   fooBarSet.add(foobar);
  }
 }

 @RequestMapping(method = RequestMethod.GET, headers = "Accept=application/xml, application/json", produces = {
   "application/json", "application/xml" })
 @ResponseBody
 public FooBar getFoobar(@RequestParam int foobarId) {
  for (FooBar foobar : fooBarSet) {
   if (foobar.getId() == foobarId)
    return foobar;
  }
  return null;
 }
 
 @RequestMapping(value= "/name" ,method = RequestMethod.GET, headers = "Accept=application/xml, application/json", produces = {
   "application/json", "application/xml" })
 @ResponseBody
 public FooBar getFoobar(@RequestParam int foobarId, @RequestParam String name) {
  for (FooBar foobar : fooBarSet) {
   if (foobar.getId() == foobarId && foobar.getName().equalsIgnoreCase(name))
    return foobar;
  }
  return null;
 }
}

Now it is time to test the web service for different inputs..

1
2
3
curl -i "http://springmvc-rest.cloudfoundry.com/foobaresample3?foobarId=1" -X GET 

curl -i "http://springmvc-rest.cloudfoundry.com/foobaresample3/name?foobarId=1&name=techiekernel1" -X GET

I have deployed the application in cloud space and it is available for you to test. You can use the above URLs to test from your side..

Source Code:

You can pull the source code from GitHub

@PathParam - JAX-RS

11:09:00 PM Posted by Satish , , , , , , 2 comments
For this tutorial, I will be using the workspace created in my tutorial RESTful Web Service with Spring 3.1. So I suggest you to read RESTful Web Service with Spring 3.1, before start reading this tutorial. In JAX-RS, you can use @PathParam to inject the value of URI parameter that defined in @Path expression, into Java method and in this tutorial I will demonstrate how to use this using Spring 3.1.0


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.techiekernel.service;

import java.util.Iterator;

import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.techiekernel.model.FooBar;
import com.techiekernel.model.FooBarSet;

/**
 * This exmaple has been created to demonstrate the @path for JAX-RS
 * 
 * @author satish
 * 
 */
@Controller
@RequestMapping("/foobaresample2")
public class FooBarServiceExample2 {

  static FooBarSet fooBarSet;

  static {
    fooBarSet = new FooBarSet();
    FooBar foobar = null;
    for (int i = 0; i < 10; i++) {
      foobar = new FooBar(i, "TechieKernel" + i);
      fooBarSet.add(foobar);
    }
  }

  /**
   * Normal URI Mapping with parameter
   * @param foobarId
   * @return
   */
  @RequestMapping(value = "/{foobarId}", method = RequestMethod.GET, headers = "Accept=application/xml, application/json", produces = {
      "application/json", "application/xml" })
  @ResponseBody
  public FooBar getFoobar(@PathVariable int foobarId) {
    for (FooBar foobar : fooBarSet) {
      if (foobar.getId() == foobarId)
        return foobar;
    }
    return null;
  }
  
  @RequestMapping(value = "/{foobarId}/{name}", method = RequestMethod.GET, headers = "Accept=application/xml, application/json", produces = {
      "application/json", "application/xml" })
  @ResponseBody
  public FooBar getFoobar(@PathVariable int foobarId, @PathVariable String name) {
    for (FooBar foobar : fooBarSet) {
      if (foobar.getId() == foobarId && foobar.getName().equalsIgnoreCase(name))
        return foobar;
    }
    return null;
  }
}

Now it is time to test the web service for different inputs..

1
2
3
curl -i "http://springmvc-rest.cloudfoundry.com/foobaresample2/1" -X GET 

curl -i "http://springmvc-rest.cloudfoundry.com/foobaresample2/1/techiekernel1" -X GET

I have deployed the application in cloud space and it is available for you to test. You can use the above URLs to test from your side..

Source Code:

You can pull the source code from GitHub

@Path - JAX-RS

6:14:00 PM Posted by Satish , , , , , , No comments
For this tutorial, I will be using the workspace created in my tutorial RESTful Web Service with Spring 3.1. So I suggest you to read RESTful Web Service with Spring 3.1, before start reading this tutorial. In JAX-RS, you can use @Path to bind URI pattern to a Java method and in this tutorial I will demonstrate how to use this using Spring 3.1.0. In this example, I will show you how to write normal URI mapping, URI mapping with parameter and also show you the use of regular expression to validate the inputs.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package com.techiekernel.service;

import java.util.Iterator;

import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.techiekernel.model.FooBar;
import com.techiekernel.model.FooBarSet;

/**
 * This exmaple has been created to demonstrate the @path for JAX-RS
 * 
 * @author satish
 * 
 */
@Controller
@RequestMapping("/foobaresample1")
public class FooBarServiceExample1 {

  static FooBarSet fooBarSet;

  static {
    fooBarSet = new FooBarSet();
    FooBar foobar = null;
    for (int i = 0; i < 10; i++) {
      foobar = new FooBar(i, "TechieKernel" + i);
      fooBarSet.add(foobar);
    }
  }

  /**
   * Normal URI Mapping with parameter
   * @param foobarId
   * @return
   */
  @RequestMapping(value = "/{foobarId}", method = RequestMethod.GET, headers = "Accept=application/xml, application/json", produces = {
      "application/json", "application/xml" })
  @ResponseBody
  public FooBar getFoobar(@PathVariable int foobarId) {
    for (FooBar foobar : fooBarSet) {
      if (foobar.getId() == foobarId)
        return foobar;
    }
    return null;
  }

  /**
   * Normal URI Mapping
   * @return
   */
  @RequestMapping(method = RequestMethod.GET, headers = "Accept=application/xml, application/json", produces = {
      "application/json", "application/xml" })
  @ResponseBody
  public FooBarSet getFoobars() {
    return fooBarSet;
  }

  /**
   * URI mapping and regular expression
   * @param foobarId
   * @return
   */
  @RequestMapping("/id/{foobarId:\\d+}")
  @ResponseBody
  public FooBar getFoobarById(@PathVariable int foobarId) {
    for (FooBar foobar : fooBarSet) {
      if (foobar.getId() == foobarId)
        return foobar;
    }
    return null;
  }

  /**
   * URI mapping and regular expression
   * @param foobarName
   * @return
   */
  @RequestMapping("/name/{foobarName:[a-zA-Z_0-9]+}")
  @ResponseBody
  public FooBar getFoobarByName(@PathVariable String foobarName) {
    for (FooBar foobar : fooBarSet) {
      if (foobar.getName().equalsIgnoreCase(foobarName))
        return foobar;
    }
    return null;
  }
}

Now it is time to test the web service for different inputs..


1
2
3
4
5
6
7
curl -i "http://springmvc-rest.cloudfoundry.com/foobaresample1/" -X GET 

curl -i "http://springmvc-rest.cloudfoundry.com/foobaresample1/1" -X GET

curl -i "http://springmvc-rest.cloudfoundry.com/foobaresample1/id/1" -X GET

curl -i "http://springmvc-rest.cloudfoundry.com/foobaresample1/name/techiekernel1" -X GET


If the inputs will be failed as per the regular expression, you will get a HTTP 404 response. I have deployed the application in cloud space and it is available for you to test. You can use the above URL to test from your side..

Source Code:

You can pull the source code from GitHub

Thursday, December 20, 2012

List and Set implementations are not marshalled with JAXB?

7:09:00 PM Posted by Satish , , , No comments
Snap of code what I was doing:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
@XmlRootElement
public class FooBar {
  public String title;
  public FooBar(String t) {
    this.title = t;
  }
}
@XmlRootElement
@XmlSeeAlso({FooBar.class})
public class FooBarSet extends ArrayList<FooBar> {
  public FooBarSet() {
    this.add(new FooBar("FooBar"));
  }
}

Then, while marshaling:

1
2
3
JAXBContext ctx = JAXBContext.newInstance(FooBar.class);
Marshaller msh = ctx.createMarshaller();
msh.marshal(new FooBar(), System.out);

This is what I saw:

1
2
<?xml version="1.0"?>
<FooBarSet/>

Why I am not getting the list of FooBar ??????

The Answer is the elements to be marshalled must be public, or have the @XMLElement anotation. The ArrayList class and my class FooBarSet do not match any of these rules. I have to define a method to offer the FooBar values, and anotate it.


So the modified class is:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@XmlRootElement
@XmlSeeAlso({FooBar.class})
public class FooBarSet extends ArrayList<FooBar> {
  public FooBarSet() {
    this.add(new FooBar("FooBar"));
  }

  @XmlElement(name = "FooBar")
 public List<FooBar> getFooBarSet() {
     return this;
 }
}

Now the output:

1
2
3
4
5
<fooBarSet>
 <FooBar>
  <title>FooBar</title>
 </FooBar>
</fooBarSet>

Wednesday, December 19, 2012

Architecture of a Modern Web Application

Some time in my career, I was working in a RFID tracking system and I was designing the real time event notification web application for that, I was using Google Map API to show the activities on a particular facility/ floor map, where RFID sensors were mounted. I tried lot of techniques and APIs and finally, I could able to push messages to the clients.. Now the question is “how did I do that???” It was a long back and at that time there were very few APIs available, which were providing server side pushing. I took the DWR Reverse AJAX and in a layman’s way to explain, clients were subscribing for the messages for a particular criteria with the server. But  to be very honest, let’s say after some 7 - 8 hours, the browsers used to be almost inactive and user couldn't even do anything, may be because of memory. Few years back, when I started using the TweetDesk a Chrome app, I realized it uses the same technique to get the messages and it is damn good and efficient. I was always very eager to know what exactly and how they are doing that.. Today facebook.com, amazon.com are very popular and they also follow some kind of the same approach… One more thing, I noticed with firebug, that for most of the operations, there is a AJAX call and only the data is flowing in terms of JSON/ text; there is no form submit to any action.. And the biggest advantage is that they are user-friendly, interactive and kick ass fast.
Long time back, there was a standard approach for all the web applications. Most of the cases, everyone was following the MVC or MVC 2 design with a service layer and DAO layer. And those days one application means a huge and fat war or an ear. Companies were using heavy application containers like weblogic and jboss, with lot of dependency. It was like a fat ugly man needs an extremely customized environment to live his life, or else he will die in no time. After that some time back companies were moving towards the SOA. A big application was further divided in to small chunks and they were interacting with each other by messages.. SOAP based web services were very powerful technique to interact with services, but now the world is going towards RESTful web services as it is simple and easy to develop. With the SOA the applications were really simple and maintaining a low cohesion. The applications used to be light weight and the servers used to be healthy all the time. But still there was a room for improvement, why the UI elements are getting streamed from server and consuming a major band width of the network.. In order to answer this question, designers moved the MVC to front-end and back end is now only the services.. If you are a back-end developer, you will be thinking, how it is possible and may be feeling insecurity about your job.. But believe me, now it is time to adapt the so called ugly JavaScript to develop beautiful and interactive applications. As the MVC concerned with front-end, there are lot of JavaScript APIs are available. So I can now conclude something that all the modern web sites like facebook.com, amazon.com and some Chrome apps like TweetDesk are using the same concept.

I was part of the Spring One Conference India Dec, 2012 and there the things were got cleared with a talk from Jeremy Grelle. Jeremy is a Spring Source Staff Engineer and one of the open source contributor for many projects.. Next, I am going give a picture of what Jeremy presented in that conference. In this article, I will take you to “Where we’ve been”, “Where we’re going” and “How we will get there”.

Static Web Pages with HTML:

When the www started, all the pages were static and served from server. There used to be separate page for separate data. The world was with URL and links.
  • Pros:
  1. Low Computation: As they are static, there is hardly any computations from a programmer point of view.
  2. Highly Cacheable: They are very easy and perfect candidate for caching.
  3. Highly Indexable: They are easily get indexed by leading search engines for their static data content.
  • Cons:
  1. Hard to Update: If you need to change anything, you have to go to the HTML file and change that  and a developer is required for the same.. Bad dependency; Isn’t it?
  2. No Personalization: You can’t have something which you really looking for.. You have to see a generic view, even if you are not bothered about the rest 90% of the content.
  3. Poor UI: UI used to be poor with bad response from server.
Dynamic Web Pages with Scripting:

After some time, when the requirements and needs changed, pages were dynamic on user inputs. Users could able to get dynamic data on the same page.
  • Pros:
  1. Dynamic: Now the pages went dynamic depending on the user inputs and different other criteria’s.
  2. Selectively Cacheable : As the pages were dynamic, so dynamic contents were not applicable for caching.
  3. Highly Indexable: They were also well indexed by the search engines.
  4. Personalization: As the user is able to provide inputs, they could able get the user a view that user is looking for.
  • Cons:

  1. High Computation: To make a page dynamic, it required a computation overhead in different manner. Lot of scripting technologies had been adopted to create dynamic web pages.
  2. Hard to Create: Same page different data representations made very difficult for the browser to cache.
  3. Poor UI: Even though the pages went dynamic, the UI used to be poor, less interactive and less responsive.
Dynamic Pages with JavaScript:

Introduction to JavaScript to the web development made the pages bit more interactive and responsive. Developers started using JavaScript for basic form validation and other activities in DOM.
  • Pros:
  1. Enhanced Usability: With the help of JavaScript, developers could able to give a good response to some of the actions, where there is no back-end data involvement.
  2. Reduced Trips to Server: As most of the validations went front-end, there was a network band width save. Developers eliminated the validation calls from server-side.
  • Cons:

  1. Abused Annoyed Users: As JavaScript is a client-side technology, lot of users started misusing that.
  2. Business Logic Often Implemented Twice: With reference to validation, sometimes the validation logic and other business logic were implemented both at client side and server-side.
AJAX – Web 2.0:

Google came up with a new approach of interacting with server. With the help of Web 2.0, Google launched Map API and Gmail. Server interaction made possible both synchronously and asynchronously with out submitting an action to the server.
  • Pros:
  1. Killer UI: With the introduction of AJAX, the look and feel of the UI went out of the world with lot of UI components.
  2. More Responsive Apps: User were able to interact with application easily without much effort and as with AJAX only the data used to be get streamed the via network, the response for a particular action used to be very fast.
  • Cons:
  1. Difficult to Cache: As there are hardly any static content, at least, it was very difficult to cache the whole page.
  2. Impossible to Index: With dynamic data, indexing a page for a search engine was quite impossible.
  3. Required JavaScript: With introduction to AJAX, there was a need for skilled UI developers in industry.
Unobtrusive JavaScript:

After some time, JavaScript proved to be a clumsy language unsuitable for serious application development. This has been largely due to inconsistent implementations of the language itself and the Document Object Model in various browsers, and the wide spread use of buggy copy-and-paste code. Run time errors were so common (and so difficult to debug), that few programmers even tried to fix them, as long as the script behaved more or less the way it was supposed to, scripts often failed completely in some browsers. At that moment the industry was again fallen back to the basic HTML way of presenting the view. And this is the time when some MVC 2 frameworks were evolved. Unobtrusive JavaScript is a general approach to the use of JavaScript in web pages. Though the term is not formally defined, its basic principles are generally understood to include Separation of functionality (the "behavior layer") from a Web page's structure/content and presentation, best practices to avoid the problems of traditional JavaScript programming (such as browser inconsistencies and lack of scalability) and progressive enhancement to support user agents that may not support advanced JavaScript functionality.
Architecture of a Old Web Application
Architecture of a Old Web Application
  • Pros:
  1. Wider Compatibility: As again the UI started coming from server as a HTML, it has a better compatibility with wider range of browsers.
  2. Just as Rich UI: As the UI was getting streamed from server, it was a raw HTML with rich components.
  3. Just as Responsive: As designers were still stick to JavaScript for some non-business related activities, the response of some activities were still good.
  • Cons:
  1. Higher development cost: Generally to make a simple application, now you need a big team with developers, architects and some managers to make sure everything happening as per the plan, which is a time consuming process..
  2. Requires thoughtful engineering: As you can’t make changes to the final product as it would have lot of dependencies and you never know one change will break how many other things. So you have to have a very good design looking at the future scope.
Client Side Applications:

Over the time designers noticed one common thing in all approaches, i.e. there are unnecessary data like HTML are also flowing from server to client and that is a major problem for slowness of the application. Now there is a significant contribution to the JavaScript APIs from the open source contributors around the world.  Business logic is no more part of the server, all moved to the front-end along with the MVC. Application state was started storing in front-end, only the permanent state has been stored in back-end. As there are no more MVC and business logic in backend, the back-end part of the applications are turning to services. SOA also has a greater impact on the current design, instead of thick  fat web application, it is getting divided in to smaller chunks to make the back-end healthy and independent with each other. Introduction of RESTful web services made front-end directly interact with services. Recently Google announced the Chrome Laptops, which are totally on the browser, so looking at the current processor architecture and memory capacity of personal computers and laptops, the browser is capable of doing complex computations and also capable of storing significant data required for a particular page.
Architecture of a Modern Web Application
Architecture of a Modern Web Application
  • Pros:
  1. Reduce server workload : As the MVC and business logic is moving to the client side, there is minimal computation at the server side, may be the CRUD operation on a object. And again with service call only the data is flowing in network, so there is a significant save in network band width.
  2. Application is highly cacheable: As the business logic and MVC is moving to front-end, front-end is making use of system resources to store data.
  3. Extremely rich UI: As I explained above, there are lot of contribution to some of the open source projects and there are lot of light weight JavaScript APIs are available now.
  • Cons:
  1. Content not indexable: As the content is 100% dynamic, there is no scope for the search engines to index the page.
  2. JavaScript: Now it is the time to learn JavaScript and start using that. Lot of companies are recruiting dedicated UI developers.
  3. Often requires a modern browser: Along with JavaScript, there are some other technologies like HTML5 and CSS3 are also adopted with context to the new architecture.. So some time user need a updated browser to use the application.
So now the web application is moving from server side application to smart clients and services. Simple templates can render on client, JSP will no more render the client side. Some of the modern techniques like web socket(for subscribing messages from server), web worker(worker and job model like Executor Framework) and DOM event will be adopted for the web application to make it more responsive and interactive.

With the current configuration standard of a personal computer or a laptop, this approach is proving it’s capability.. As discussed about some of the web sites like facebook.com, amazon.com, ebay.com etc. and some of the browser apps like TweetDesk, RSS Readers etc. are very popular for their performance.

The definition of back-end and front end are shifting to front-end != client and back-end != server. There are lot technologies are evolving and there is a huge support from the open source contributors. Now it is the time for a java developers to take interest in JavaScript and start learning the new technologies like css3, HTML5 with some JavaScript libraries like jQuery, s2js, cujo.js, scripted, SockJS, monty-hall, monty-hall-ui etc.

Even though, I have drafted this article for you guys, I want to give the credit to Jeremy Grelle, SpringSource Staff Engineer and open source contributor. I would also like to thank VMWare for inviting me to SpringOne India 2012 Conference.

I will soon be developing some small applications using this architecture and will probably deploy those in the Cloud, so that you people can play around that.

Saturday, December 15, 2012

RESTful Web Service with Spring 3.1

8:22:00 PM Posted by Satish , , , , , , , , , 9 comments
I posted lot of tutorials to create RESTful web services using different APIs like JAX-RS With GlassFish Jersey, JAX-RS With Jboss RESTEasy and JAX-RS With Apache CXF. I also posted the tutorials for Spring integration in Spring And Jersey, Spring and RESTEasy and Spring And CXF. But when it comes to RESTful web services, I personally like to use Spring 3.1 MVC. Some time back when RESTful web services were booming in industry, SpringSource developers released Spring 3.1 with REST support. They used the existing Spring MVC request mapping and took the help of JAX-RS 2.0 implementation for JSON and XML marshaling/ demarshaling. That is how they made it very simple.


This tutorial, I am going to demonstrate how to build a RESTful web service using Spring 3.1 MVC. Not only I will be creating a demo, along with that I will be demonstrating the CRUD operation with one of the model object. In this case I will be using FooBar as model object.

I am going to use the following tools and technologies in this turorial.
  • Spring 3.1.0.RELEASE
  • jackson-mapper-asl 1.9.9
  • jaxb-api 2.2.7
  • JDK 1.7
  • Tomcat 7.0
  • Maven
  • Eclipse 
I am going to take you to the following areas in this tutorial.
  • Service/Controller
  • Model Class
  • Spring MVC Context Configuration
  • Spring Integration With Web Container
  • Application Deployment
  • Testing
  • Source Code
Before start coding let's create a dynamic web project using the following maven command.

1
mvn archetype:generate -DgroupId=com.techiekernel.rest -DartifactId=SpringMVC-REST -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

After executing, the project will be get created with pom.xml file. As I am using JDK 7 and annotations, I have to specify the updated maven plugin. After giving the Jackson, JAXB and Spring dependency, the pom.xml looks as following.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.techiekernel.rest</groupId>
  <artifactId>SpringMVC-REST</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>SpringMVC-REST Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <properties>
    <jackson-mapper-asl.version>1.9.9</jackson-mapper-asl.version>
    <jaxb-api.version>2.2.7</jaxb-api.version>
  </properties>

  <dependencies>

    <!-- Spring 3 dependencies -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>3.1.0.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>3.1.0.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>3.1.0.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>3.1.0.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.codehaus.jackson</groupId>
      <artifactId>jackson-mapper-asl</artifactId>
      <version>${jackson-mapper-asl.version}</version>
    </dependency>
    <dependency>
      <groupId>javax.xml.bind</groupId>
      <artifactId>jaxb-api</artifactId>
      <version>${jaxb-api.version}</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.1.1</version>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
        </configuration>
      </plugin>
    </plugins>
    <finalName>SpringMVC-REST</finalName>
  </build>
</project>

Service/Controller:

In this case, we are going to write the web service in our Spring MVC controller. As you can see I have created POST, PUT, GET, DELETE methods to demonstrate the CRUD operations on FooBar. All the other configurations  are well self explanatory.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package com.techiekernel.service;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.techiekernel.model.FooBar;

@Controller
@RequestMapping("/foobar")
public class FooBarService {

  static Set<FooBar> fooBars;

  static {
    fooBars = new HashSet<FooBar>();
    FooBar foobar = null;
    for (int i = 0; i < 10; i++) {
      foobar = new FooBar(i, "Techie Kernel " + i);
      fooBars.add(foobar);
    }
  }

  @RequestMapping(value = "/{foobarId}", method = RequestMethod.GET, headers = "Accept=application/xml, application/json", produces = {
      "application/json", "application/xml" })
  @ResponseBody
  public FooBar getFoobar(@PathVariable int foobarId) {
    for (FooBar foobar : fooBars) {
      if (foobar.getId() == foobarId)
        return foobar;
    }
    return null;
  }

  @RequestMapping(method = RequestMethod.GET, headers = "Accept=application/xml, application/json", produces = {
      "application/json", "application/xml" })
  @ResponseBody
  public Set<FooBar> getFoobars() {
    return fooBars;
  }

  @RequestMapping(value = "/{foobarId}", method = RequestMethod.PUT, headers = "Accept=application/xml, application/json", produces = {
      "application/json", "application/xml" }, consumes = {
      "application/json", "application/xml" })
  @ResponseBody
  public FooBar editFoobar(@RequestBody FooBar foobar,
      @PathVariable int foobarId) {
    for (FooBar foobar1 : fooBars) {
      if (foobarId == foobar1.getId()) {
        foobar1.setId(foobar.getId());
        foobar1.setName(foobar.getName());
        return foobar1;
      }
    }
    return null;
  }

  @RequestMapping(value = "/{foobarId}", method = RequestMethod.DELETE, headers = "Accept=application/xml, application/json", produces = {
      "application/json", "application/xml" })
  @ResponseBody
  public boolean deleteFoobar(@PathVariable int foobarId) {
    System.out.println("Delete call.");
    Iterator<FooBar> fooIterator = fooBars.iterator();
    while (fooIterator.hasNext()) {
      FooBar foobar = fooIterator.next();
      System.out.println(foobar);
      if (foobar.getId() == foobarId) {
        fooIterator.remove();
        return true;
      }
    }
    return false;
  }

  @RequestMapping(method = RequestMethod.POST, headers = "Accept=application/xml, application/json", produces = {
      "application/json", "application/xml" }, consumes = {
      "application/json", "application/xml" })
  @ResponseBody
  public boolean createFoobar(@RequestBody FooBar fooBar) {
    return fooBars.add(fooBar);
  }

}

Model Class:

This is the FooBar our model class which has to be marshaled and demarshaled by JAX-RS APIs. So be very care full to annotate @XmlRootElement and @JsonAutoDetect. These two annotations will mark the class for marshaling and marshaling.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.techiekernel.model;

import javax.xml.bind.annotation.XmlRootElement;

import org.codehaus.jackson.annotate.JsonAutoDetect;

@XmlRootElement
@JsonAutoDetect
public class FooBar {
  int id;
  String name;

  public FooBar() {
    this.id = 1;
    this.name = "Techie Kernel";

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

  }

  public int getId() {
    return id;
  }

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

  public String getName() {
    return name;
  }

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

  @Override
  public String toString() {
    return "FooBar [id=" + id + ", name=" + name + ", hashCode()="
        + hashCode() + "]";
  }
  
  @Override
  public int hashCode() {
    // TODO Auto-generated method stub
    return this.id;
  }
  
  @Override
  public boolean equals(Object obj) {
    if (obj instanceof FooBar) {
      if(this.id == ((FooBar)obj).id)
        return true;
    }
    return false;
  }
  
}

Spring MVC Context Configuration:

Now it's time to save the Spring MVC configuration in a xml file. Let's save the mvc-dispacher-servlet.xml in WEB-INF folder.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:context="http://www.springframework.org/schema/context"
  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/context 
        http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
  <mvc:annotation-driven />
  <context:component-scan base-package="com.techiekernel.service" />
</beans>

Spring Integration With Web Container:

The integration is going to be in web.xml. Register Spring “ContextLoaderListener” listener class and specify the Spring MVC dispacher servlet “org.springframework.web.servlet.DispatcherServlet“ as front controller for all requests.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<web-app id="WebApp_ID" version="2.4"
  xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
  http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <display-name>Spring MVC REST</display-name>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
  </context-param>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>
                    org.springframework.web.servlet.DispatcherServlet
                </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
 
  <servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

Application Deployment:

Now every thing is ready and time to build for creating a war file.

1
mvn clean install;

On successful completion of the above command a war file will be get created in target folder. Copy the war file to webapp folder of your tomcat and start the tomcat. For you people to test, I have put the application in the VMWare Cloud. You can access the application using this URL.

Testing:

I could have wrote a Junit test to test all the services. But for a better user experience, I would suggest you to test using one of the REST tools with browser. I am using REST Client addon from Mozzila Firefox. As I have told I am going to demonstrate the CRUD operations on model object FooBar, I will be doing the all four GET, POST, PUT and DELETE operations using the Cloud URL. I would request you not to hit the URLs blindly, as at some time there there will be a change in data or there will be no data, so better hit the GET URL first to see the data status. I will be using UNIX curl command here to give you a idea for testing. 

http://localhost:8080/SpringMVC-REST - localhost tomcat URL
http://springmvc-rest.cloudfoundry.com - Cloud URL


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Get:
curl -i http://springmvc-rest.cloudfoundry.com/foobar -H "accept:application/json" -X GET
curl -i http://springmvc-rest.cloudfoundry.com/foobar/1 -H "accept:application/json" -X GET
curl -i http://springmvc-rest.cloudfoundry.com/foobar/1 -H "accept:application/xml" -X GET

PUT:
curl -i http://springmvc-rest.cloudfoundry.com/foobar/1 -H "accept:application/json" -H "content-Type:application/json" -X PUT -d "{  \"id\": 1,  \"name\": \"Techie Kernel-modified\"}"

POST:
curl -i http://springmvc-rest.cloudfoundry.com/foobar -H "accept:application/json" -H "content-Type:application/json" -X POST -d "{  \"id\": 10,  \"name\": \"Techie Kernel 10\"}"

DELETE:
curl -i http://springmvc-rest.cloudfoundry.com/foobar/10 -H "accept:application/json" -X DELETE


Source Code:

You can pull the code from GitHub.