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

Showing posts with label CXF. Show all posts
Showing posts with label CXF. Show all posts

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.

Sunday, December 9, 2012

JAX-RS With Apache CXF

8:12:00 PM Posted by Satish , , , , , , , , 1 comment
Apache CXF helps you build and develop services using frontend programming APIs, like JAX-WS and JAX-RS. These services can speak a variety of protocols such as SOAP, XML/HTTP, RESTful HTTP, or CORBA and work over a variety of transports such as HTTP, JMS or JBI. In this tutorial, I will show you how to use Apache CXF to create a simple RESTful web service.


I am going to use the following tools and technologies.
  • Apache CXF 2.2.12
  • JDK 1.7
  • Tomcat 7.0
  • Maven
  • Eclipse 
I am going to take you to the following areas in this tutorial.
  • Service Class and Mapping Configuration
  • BootStrap Implimentation
  • Front Controller Configuration
  • 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=JAXRS-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 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
<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>JAXRS-CXF</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>JAXRS-Jersey Maven Webapp</name>
  <url>http://maven.apache.org</url>


  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
      <version>2.2.12</version>
      <type>jar</type>
      <scope>compile</scope>
    </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>JAXRS-CXF</finalName>
  </build>
</project>

Service Class and Mapping Configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
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;

@Path("/foobar")
public class FooBarService {
  @GET
  @Path("/{param}")
  public Response getMsg(@PathParam("param") String msg) {
 
    String output = "FooBar say : " + msg;
 
    return Response.status(200).entity(output).build();
 
  }
}

Front Controller Configuration:

As we are not using any framework like spring we have to write our own implimentation to make the service available. We are going to achieve this giving a implimentation to "javax.ws.rs.core.Application".

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

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.core.Application;
import javax.ws.rs.ext.Provider;

@Provider
public class CXFApplication extends Application {
  private Set<Object> singletons = new HashSet<Object>();
   
  public CXFApplication() {
    singletons.add(new FooBarService());
  }
 
  @Override
  public Set<Object> getSingletons() {
    return singletons;
  }

  @Override
  public Set<Class<?>> getClasses() {
    // TODO Auto-generated method stub
    return Collections.emptySet();
  }
}

Front Controller Configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<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>JAXRS-CXF</display-name>
  <servlet>
    <servlet-name>CXFApplication</servlet-name>
    <display-name>CXFApplication</display-name>
    <servlet-class>
      org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet
    </servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>com.techiekernel.rest.CXFApplication</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>CXFApplication</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/JAXRS-CXF/ws/foobar/foobar

Output:

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

1
FooBar say : foobar

Source Code:

You can pull the code from GitHub.

Thursday, December 6, 2012

RESTful Web Services

REST (Representational State Transfer) is an architectural style which is based on web-standards and the HTTP protocol. 

In a REST based architecture everything is a resource. A resource is accessed via a common interface based on the HTTP standard methods. In a REST based architecture you typically have a REST server which provides access to the resources and a REST client which accesses and modify the REST resources. Every resource should support the HTTP common operations. Resources are identified by global IDs. REST allows that resources have different representations, e.g. text, xml, json etc. The rest client can ask for specific representation via the HTTP protocol (content negotiation).
The PUT, GET, POST and DELETE methods are typical used in REST based architectures.
  • GET defines a reading access of the resource without side-effects. The resource is never changed via a GET request, e.g. the request has no side effects (idempotent).
  • PUT creates a new resource, must also be idempotent.
  • DELETE removes the resources. The operations are idempotent, they can get repeated without leading to different results.
  • POST updates an existing resource or creates a new resource.
RESTFul webservices are based on the HTTP methods and the concept of REST. A RESTFul webservice typically defines the base URI for the services, the supported MIME-types (XML, Text, JSON, user-defined) and the set of operations (POST, GET, PUT, DELETE) which are supported.
Java defines REST support via the Java Specification Request 311 (JSR). This specificiation is called JAX-RS (The Java API for RESTful Web Services). JAX-RS uses annotations to define the REST relevance of Java classes.

I suggest to read the following two article before start learing the REST (JAX-RS) web service. I wrote these articles keeping in mind atleast you get a over all idea of web service.


Before Learning Java Web Service

XML Parsing using Java

1. JAX-RS With GlassFish Jersey

2. JAX-RS With Jboss RESTEasy

3. JAX-RS With Apache CXF

4. Spring And Jersey

5. Spring and RESTEasy

6. Spring And CXF

7. RESTful Web Service with Spring 3.1

8. @Path - JAX-RS

9. @PathParam - JAX-RS

10. @RequestParam - JAX-RS

In this article I have not completed all the topics.. There are lot more techniques and tricks in RESTful web services. I was going through Spring 3.1.0 developer docs and it is pretty good from understanding point of view. So I would suggest you to refer Spring 3.1.0 or some other implementations of JAX-RS for a much better knowledge. I am short of time and next I will be working towards some modern technologies, so that I can get you some implementation for what I posted last week in my article Architecture of a Modern Web Application.