Overview:
This is Part 1 of the article on RESTful WS with Apache CXF. In this article we will look at how you can do XML/HTTP based RESTful WS with Apache CXF. We're using the CXF support on JAX-RS (JSR-311) for this. The sample code can be found here.
You can also follow the Part 2.
Prerequisite:JDK >= 1.5.x
Project Structure: Following is the project structure I have used (Maven WAR project).
Step 2: Creating POJO Classes and Service Implementation
Employee.java
Employees.java - This is used to hold a collection object of Employee.java
Read more about Apache CXF - JAX-RS basics.
Step 3: Exposing the Service Beans as RESTful Web Service
Step 4: Updating the web.xml to Register the CXF Servlet.
mvn clean install
Step 6: Deploying the Service
Now you can deploy this service on to any container. Here we'll deploy this on Tomcat server.
Step 7: Testing the RESTful Web Service using CURL
We're going to test our Web Service using CURL, which I found as a very easy way to send REST Calls. I found this very nice blog about RESTing with Curl.
Installing CURL
sudo apt-get install curl
-I am using Ubuntu, if you're using Win or Mac, please do the necessary to install curl.
Now, after successfully installing CURL, we are ready to test the services.
GET Resources:
- Retrieving all the employee resources.
- Retrieving a employee resource for a given id(id = 1).
POST a Resource: Adding a new employee resource.
- Adding the new employee record in the add.xml file.
PUT a Resource: Updating an existing employee resource.
- Updating an existing employee record in the update.xml file.
DELETE a Resource: Deleting an employee for a given id (id=2)
Summary:
This tutorial looked at how we can create XML RESTful Web Service using Apache CXF and test the services using CURL. You can find the sample code here.
This is Part 1 of the article on RESTful WS with Apache CXF. In this article we will look at how you can do XML/HTTP based RESTful WS with Apache CXF. We're using the CXF support on JAX-RS (JSR-311) for this. The sample code can be found here.
You can also follow the Part 2.
Prerequisite:JDK >= 1.5.x
Maven >= 2.2.x
Project Structure: Following is the project structure I have used (Maven WAR project).
<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>org.fazlan</groupId>
<artifactId>org.fazlan.employee.cxf.xmlrest.service</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>org.fazlan.employee.cxf.xmlrest.service</name>
<url>http://maven.apache.org</url>
<build>
<finalName>CXFEmployeeXmlRESTService</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Spring framework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</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-databinding-aegis</artifactId>
<!-- 2.4.4 or 2.5.0 -->
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>2.4.0</version>
</dependency>
</dependencies>
<properties>
<org.springframework.version>3.1.1.RELEASE</org.springframework.version>
<cxf.version>2.4.6</cxf.version>
</properties>
</project>
Step 2: Creating POJO Classes and Service Implementation
Employee.java
package org.fazlan.employee.cxf.xmlrest.service.beans;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import java.io.Serializable;
@XmlType(
name = "EmployeeType",
namespace = "org.fazlan.employee.cxf.xmlrest.service.beans",
propOrder = {"id", "firstName", "lastName"})
@XmlRootElement(
name = "Employee",
namespace = "org.fazlan.employee.cxf.xmlrest.service.beans")
public class Employee implements Serializable {
private Long id;
private String firstName;
private String lastName;
public Employee() {
}
public Employee(Long id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Employee)) return false;
Employee employee = (Employee) o;
return !(firstName != null ? !firstName.equals(employee.firstName) : employee.firstName != null) && !(id != null ? !id.equals(employee.id) : employee.id != null) && !(lastName != null ? !lastName.equals(employee.lastName) : employee.lastName != null);
}
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
}
Employees.java - This is used to hold a collection object of Employee.java
package org.fazlan.employee.cxf.xmlrest.service.beans;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import java.util.Collection;
@XmlType(
name = "EmployeesType",
namespace = "org.fazlan.employee.cxf.xmlrest.service.beans")
@XmlRootElement(
name = "Employees",
namespace = "org.fazlan.employee.cxf.xmlrest.service.beans")
public class Employees {
private Collection<Employee> employees;
public Employees() {
}
public Employees(Collection<Employee> employees) {
setEmployees(employees);
}
@XmlElement(name = "employee",required = true)
@XmlElementWrapper(name = "employees")
public Collection<Employee> getEmployees() {
return employees;
}
public void setEmployees(Collection<Employee> employees) {
this.employees = employees;
}
}
IEmployeeService.java - Service Interfacepackage org.fazlan.employee.cxf.xmlrest.service.services;
import org.fazlan.employee.cxf.xmlrest.service.beans.Employee;
import org.fazlan.employee.cxf.xmlrest.service.beans.Employees;
import javax.ws.rs.core.Response;
public interface IEmployeeService {
Employee get(Long id);
Employees getAll();
Response add(Employee employee);
Response update(Employee employee);
Response delete(Long id);
}
EmployeeService.java - Implementation of the service.
NOTE: This service class has been annotated to produce and consume certain methods in XML(application/xml) as the mime-type. Read more about Apache CXF - JAX-RS basics.
package org.fazlan.employee.cxf.xmlrest.service.services;
import org.fazlan.employee.cxf.xmlrest.service.beans.Employee;
import org.fazlan.employee.cxf.xmlrest.service.beans.Employees;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import java.util.HashMap;
import java.util.Map;
@Path("/employeeservice/")
@Produces("application/xml")
public class EmployeeService implements IEmployeeService {
private static final Map<Long, Employee> EMPLOYEE_MAP = new HashMap<Long, Employee>();
private static long index = 3L;
static {
EMPLOYEE_MAP.put(1L, new Employee(1L, "First Name 1", "Last Name 1"));
EMPLOYEE_MAP.put(2L, new Employee(2L, "First Name 2", "Last Name 2"));
}
@GET
@Path("/get/{id}")
public Employee get(@PathParam("id") Long id) {
return EMPLOYEE_MAP.get(id);
}
@GET
@Path("/getall/")
public Employees getAll() {
return new Employees(EMPLOYEE_MAP.values());
}
@POST
@Path("/add/")
@Consumes("application/xml")
public Response add(Employee employee) {
System.out.println("Adding :" + employee);
employee.setId(index++);
update(employee);
return Response.status(Response.Status.OK).build();
}
@PUT
@Path("/update/")
@Consumes("application/xml")
public Response update(Employee employee) {
EMPLOYEE_MAP.put(employee.getId(), employee);
return Response.status(Response.Status.OK).build();
}
@DELETE
@Path("/delete/{id}/")
public Response delete(@PathParam("id") Long id) {
Employee e = EMPLOYEE_MAP.remove(id);
System.out.println("Deleted :" + e);
return Response.status(Response.Status.OK).build();
}
}
Read more about Apache CXF - JAX-RS basics.
Step 3: Exposing the Service Beans as RESTful Web Service
<?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:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd">
<!-- do not use import statements if CXFServlet init parameters link to this beans.xml -->
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
<jaxrs:server id="employeeService" address="/">
<jaxrs:serviceBeans>
<ref bean="employeeServiceBean"/>
</jaxrs:serviceBeans>
<jaxrs:extensionMappings>
<entry key="xml" value="application/xml" />
<entry key="json" value="application/json" />
</jaxrs:extensionMappings>
<jaxrs:features>
<cxf:logging/>
</jaxrs:features>
</jaxrs:server>
<bean id="employeeServiceBean" class="org.fazlan.employee.cxf.xmlrest.service.services.EmployeeService"/>
</beans>
Step 4: Updating the web.xml to Register the CXF Servlet.
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>CXF Web Service Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/app-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
Step 5: Building the Project mvn clean install
Step 6: Deploying the Service
Now you can deploy this service on to any container. Here we'll deploy this on Tomcat server.
Step 7: Testing the RESTful Web Service using CURL
We're going to test our Web Service using CURL, which I found as a very easy way to send REST Calls. I found this very nice blog about RESTing with Curl.
Installing CURL
sudo apt-get install curl
-I am using Ubuntu, if you're using Win or Mac, please do the necessary to install curl.
Now, after successfully installing CURL, we are ready to test the services.
GET Resources:
- Retrieving all the employee resources.
curl -v -H "Accept: application/xml" http://localhost:8080/CXFEmployeeXmlRESTService/employeeservice/getall
- Retrieving a employee resource for a given id(id = 1).
curl -v -H "Accept: application/xml" http://localhost:8080/CXFEmployeeXmlRESTService/employeeservice/get/1
POST a Resource: Adding a new employee resource.
- Adding the new employee record in the add.xml file.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Employee xmlns:ns2="org.fazlan.employee.cxf.xmlrest.service.beans">
<id>3</id>
<firstName>First Name1</firstName>
<lastName>Last Name1</lastName>
</ns2:Employee>
curl -v -H "Accept: application/xml" -H "Content-type: application/xml" -X POST -d @add.xml http://127.0.0.1:8080/CXFEmployeeXmlRESTService/employeeservice/add
- Updating an existing employee record in the update.xml file.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Employee xmlns:ns2="org.fazlan.employee.cxf.xmlrest.service.beans">
<id>1</id>
<firstName>Updated First Name1</firstName>
<lastName>Updated Last Name1</lastName>
</ns2:Employee>
curl -v -H "Accept: application/xml" -H "Content-type: application/xml" -X PUT -d @update.xml http://127.0.0.1:8080/CXFEmployeeXmlRESTService/employeeservice/update/
DELETE a Resource: Deleting an employee for a given id (id=2)
curl -i -H "Accept: application/xml" -X DELETE http://localhost:8080/CXFEmployeeXmlRESTService/employeeservice/delete/2/
Summary:
This tutorial looked at how we can create XML RESTful Web Service using Apache CXF and test the services using CURL. You can find the sample code here.
No comments:
Post a Comment