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

Showing posts with label WEB SERVICE. Show all posts
Showing posts with label WEB SERVICE. Show all posts

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

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.

Friday, December 14, 2012

Spring And CXF

8:38:00 PM Posted by Satish , , , , , , , , , No comments
This tutorial I am going to demonstrate how to integrate Apache CXF and Spring 3 to create a RESTFul web service. Using this I am going to show how to inject a bean to the web service class. In this example I will be injecting the service layer object to web service.
I am going to use the following tools and technologies.
  • CXF 2.5.0
  • Spring 3.0.5.RELEASE
  • JDK 1.7
  • Tomcat 7.0
  • Maven
  • Eclipse 
I am going to take you to the following areas in this tutorial.
  • Service Layer Interface
  • Service Layer Class
  • Web Service Class
  • Spring Bean Configuration
  • Configuration for Spring and Apache CXF
  • Application Deployment
  • Testing
Before start coding let's create a dynamic web project using the following maven command. 

1
mvn archetype:generate -DgroupId=com.techiekernel.rest -DartifactId=Spring-CXF -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 CXF 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
70
71
72
73
74
<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>Spring-CXF</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>JAXRS-CXF Maven Webapp</name>
  <url>http://maven.apache.org</url>

  <properties>
    <spring.version>3.0.5.RELEASE</spring.version>
    <cxf.version>2.5.0</cxf.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxws</artifactId>
      <version>${cxf.version}</version>
    </dependency>

    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
      <version>${cxf.version}</version>
    </dependency>

    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-transports-http</artifactId>
      <version>${cxf.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</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-oxm</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.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>Spring-CXF</finalName>
  </build>
</project>

Service Layer Interface:

As I will show the Spring IOC or dependency injection, I am going to create the service layer interface and later a implimentation for the same.

1
2
3
4
5
package com.techiekernel.service;

public interface FooBarService {
  public String getMessage(String msg);
}

Service Layer Class:

1
2
3
4
5
6
7
8
package com.techiekernel.service;

public class FooBarServiceImpl implements FooBarService{
  public String getMessage(String msg) {
    String output = "FooBar say : " + msg;
    return output;
  }
}

Web Service Class:

 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
package com.techiekernel.rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.techiekernel.service.FooBarService;

@Component
public class FooBarWS {
  //@Autowired
  FooBarService fooBarService;
 
  @GET
  @Path("/{param}")
  public Response getMessage(@PathParam("param") String msg) {
    return Response.status(200).entity(fooBarService.getMessage(msg)).build();
  }

  public FooBarService getFooBarService() {
    return fooBarService;
  }

  public void setFooBarService(FooBarService fooBarService) {
    this.fooBarService = fooBarService;
  }
  
}

Spring Bean Configuration:

Now it is time to cleate the configuration for spring beans in applicationContext.xml. It is very much required to place the following configuration in classpath, so that container will read from the deployment descriptor.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<?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:jaxrs="http://cxf.apache.org/jaxrs"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

  <bean id="FooBarService" class="com.techiekernel.service.FooBarServiceImpl" />

  <bean id="fooBarWsClass" class="com.techiekernel.rest.FooBarWS">
    <property name="fooBarService" ref="FooBarService"></property>
  </bean>
  <jaxrs:server id="fooBarWs" address="/foobar">
    <jaxrs:serviceBeans>
      <ref bean="fooBarWsClass" />
    </jaxrs:serviceBeans>
  </jaxrs:server>
</beans>

Configuration for Spring and CXF:

The integration is going to be in web.xml. Register Spring “ContextLoaderListener” listener class and specify the CXF servlet “org.apache.cxf.transport.servlet.CXFServlet“ as front controller for web services.

 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
<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 CXF</display-name>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
    <listener>
  <listener-class>
                        org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    <servlet>
    <servlet-name>CXFServlet</servlet-name>
    <display-name>CXF Servlet</display-name>
    <servlet-class>
      org.apache.cxf.transport.servlet.CXFServlet
    </servlet-class>
    <load-on-startup>2</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/ws/*</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.

Testing:

Once tomcat is started use the following url to access the web service.

1
http://localhost:8080/Spring-CXF/ws/foobar/techiekernel

Output:

Once you hit the url in the browser, you are going to get the following output.


1
FooBar say : techiekernel


Source Code:

You can pull the code from GitHub.