Showing posts with label XML. Show all posts
Showing posts with label XML. Show all posts

Thursday, April 12, 2012

Part 1: RESTful WS with Apache CXF - XML

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
Maven >= 2.2.x

Project Structure: Following is the project structure I have used (Maven WAR project).

Step 1: Maven Dependencies (pom.xml)
 <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 Interface

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.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


PUT a Resource: Updating an existing employee resource.
- 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.

Wednesday, April 4, 2012

Spring: Spring AOP with XML Configuration

Overview:
This post will look how you could easily configure Spring AOP. Also, this article tries to focus on XML base configuration rather than AspectJ annotations. Moreover, XML based configuration will not have any restrictions on the under lying JDK version (e.i; for annotation based configuration to work, we require JDK 1.5 or higher). Sample code can be found here.

We'll be looking at the following AOP configurations,
  • Before - Runs before the execution of a method.
  • After - Runs after the execution of a method.
  • AfterReturning - Runs after the method returns a result.
  • AfterThrowing - Runs after the methods throws an exception.
  • Around - Runs whilst the method is executing.
Project Structure: Following diagram show the project structure I have used for this post.



Step 1: Maven Dependencies
 <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>spring-aop</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>spring-aop</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- JUnit testing framework -->
<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-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjrt</artifactId>
   <version>${org.aspectj.version}</version>
</dependency>
<dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>${org.aspectj.version}</version>
</dependency>
</dependencies>
<properties>
<org.aspectj.version>1.6.11</org.aspectj.version>
<org.springframework.version>3.1.1.RELEASE</org.springframework.version>
</properties>
</project>
Step 2: Creating POJO Classes and Service Implementation
Person.java
 public class Person {
private long id;
private String firstName;
private String lastName;
private static long ID_INDEXER = 1;
public Person() {
id = ID_INDEXER++;
}
public Person(String firstName, String lastName) {
this();
this.firstName = firstName;
this.lastName = lastName;
}
public long getId() {
return 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;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
}
Service Interface:
 public interface ICRUDService<T> {
Serializable save(T t);
void update(T t);
T get(Serializable id);
List<T> getAll();
}
Service Implementation:
 public class PersonService implements ICRUDService<Person>{
private static final Map<Serializable, Person> PERSON_MAP = new HashMap<Serializable, Person>();
public Serializable save(Person person) {
update(person);
return person.getId();
}
public void update(Person person) {
PERSON_MAP.put(person.getId(), person);
}
public Person get(Serializable id) {
return PERSON_MAP.get(id);
}
public List<Person> getAll() {
return new ArrayList<Person>(PERSON_MAP.values());
}
}

Step 3: Creating the Aspect Class
 public class LoggerAspect {
public void before(JoinPoint joinpoint) {
System.out.println("Log before of method --:> " + joinpoint.getSignature().getName());
if (joinpoint.getArgs().length > 0) {
 System.out.println(joinpoint.getArgs()[0]);
}
System.out.println("---------------------------------");
}
public void after(JoinPoint joinpoint) {
System.out.println("Log after of method --:> " + joinpoint.getSignature().getName());
System.out.println("---------------------------------");
}
public Object around(ProceedingJoinPoint joinpoint) throws Throwable {
long t1 = System.currentTimeMillis();
System.out.println("Log proceed of method --:> " + joinpoint.getSignature().getName());
Object obj = joinpoint.proceed();
System.out.println("Time taken to execute : " + (System.currentTimeMillis() - t1) + " milliseconds.");
System.out.println("---------------------------------");
return obj;
}
public void afterReturning(JoinPoint joinpoint, Object result) {
System.out.println("Log afterReturning of method --:> " + joinpoint.getSignature().getName()
   + " [" + result + "]");
System.out.println("---------------------------------");
}
public void afterThrowing(JoinPoint joinpoint, Throwable error) {
System.out.println("Log afterThrowing of method --:> " + joinpoint.getSignature().getName()
   + " [" + error.getMessage() + "]");
System.out.println("---------------------------------");
}
}

Step 4: Configuring the Spring Beans and Wiring the AOP to the Service Implementation
 <?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="personService" class="org.fazlan.spring.service.PersonService"/>
<!-- AOP Aspects-->
<bean id="loggerAspect" class="org.fazlan.spring.aop.LoggerAspect"/>
<aop:config>
<aop:pointcut id="personServicePC" expression="execution(* org.fazlan.spring.service.ICRUDService.*(..))"/>
<aop:aspect id="preLoggingAspects" ref="loggerAspect">
  <!-- @Before Aspect-->
  <aop:before method="before" pointcut-ref="personServicePC"/>
  <!-- @After Aspect-->
  <aop:after method="after" pointcut-ref="personServicePC"/>
  <!-- @After Aspect-->
  <aop:around method="around" pointcut-ref="personServicePC"/>
  <!-- @AfterReturning Aspect-->
  <aop:after-returning method="afterReturning" returning="result" pointcut-ref="personServicePC"/>
  <!-- @AfterThrowing Aspect-->
  <aop:after-throwing method="afterThrowing" throwing="error" pointcut-ref="personServicePC"/>
</aop:aspect>
</aop:config>
</beans>

Step 5: Trying out the AOP with a Simple Application Client
 public class Main {
public static void main(String... args) {
 ApplicationContext context =
 new ClassPathXmlApplicationContext("org/fazlan/spring/aop/spring-conf-application.xml");
 ICRUDService<Person> service = (ICRUDService<Person>) context.getBean("personService");
 Serializable id = service.save(new Person("First Name", "Second Name"));
 Person p1 = service.get(id);
 p1.setFirstName("Updated First Name");
 service.update(p1);
 service.save(new Person("Fazlan", "Sabar"));
 for(Person p: service.getAll()) {
   System.out.println(p);
 }
}
}
Sample output Generated:
 Apr 4, 2012 1:03:19 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [org/fazlan/spring/aop/spring-conf-application.xml]
Apr 4, 2012 1:03:19 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@56c163f: defining beans [personService,loggerAspect,org.springframework.aop.config.internalAutoProxyCreator,personServicePC,org.springframework.aop.aspectj.AspectJPointcutAdvisor#0,org.springframework.aop.aspectj.AspectJPointcutAdvisor#1,org.springframework.aop.aspectj.AspectJPointcutAdvisor#2,org.springframework.aop.aspectj.AspectJPointcutAdvisor#3,org.springframework.aop.aspectj.AspectJPointcutAdvisor#4]; root of factory hierarchy
Log before of method --:> save
Person{id=1, firstName='First Name', lastName='Second Name'}
---------------------------------
Log proceed of method --:> save
Log after of method --:> save
---------------------------------
Time taken to execute : 1 milliseconds.
---------------------------------
Log afterReturning of method --:> save [1]
---------------------------------
Log before of method --:> get
1
---------------------------------
Log proceed of method --:> get
Log after of method --:> get
---------------------------------
Time taken to execute : 0 milliseconds.
---------------------------------
Log afterReturning of method --:> get [Person{id=1, firstName='First Name', lastName='Second Name'}]
---------------------------------
Log before of method --:> update
Person{id=1, firstName='Updated First Name', lastName='Second Name'}
---------------------------------
Log proceed of method --:> update
Log after of method --:> update
---------------------------------
Time taken to execute : 0 milliseconds.
---------------------------------
Log afterReturning of method --:> update [null]
---------------------------------
Log before of method --:> save
Person{id=2, firstName='Fazlan', lastName='Sabar'}
---------------------------------
Log proceed of method --:> save
Log after of method --:> save
---------------------------------
Time taken to execute : 0 milliseconds.
---------------------------------
Log afterReturning of method --:> save [2]
---------------------------------
Log before of method --:> getAll
---------------------------------
Log proceed of method --:> getAll
Log after of method --:> getAll
---------------------------------
Time taken to execute : 0 milliseconds.
---------------------------------
Log afterReturning of method --:> getAll [[Person{id=1, firstName='Updated First Name', lastName='Second Name'}, Person{id=2, firstName='Fazlan', lastName='Sabar'}]]
---------------------------------
Person{id=1, firstName='Updated First Name', lastName='Second Name'}
Person{id=2, firstName='Fazlan', lastName='Sabar'}  

Summary:
We looked at how Spring framework allows us to easily configure AOP via XML with little configuration.