Saturday, 26 February 2011

CXF hello world tutorial

This example shows how to make cxf web service.

Get the bean ready:
package com.company.auth.bean;

import java.io.Serializable;
import java.util.Set;

public class Employee implements Serializable {

private static final long serialVersionUID = 1L;
private String gid;
private String lastName;
private String firstName;
private Set<String> privileges;

public Employee() {}

public Set<String> getPrivileges() {
return privileges;
}

public void setPrivileges(Set<String> privileges) {
this.privileges = privileges;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getGid() {
return gid;
}

public void setGid(String gid) {
this.gid = gid;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public boolean isUserInRole(String role) {
if(privileges == null) { return false; }
else { return privileges.contains(role); }
}

}

First off, you need to download Apache CXF and drop the necessary .jars in your WEB-INF/lib directory:
aopalliance-1.0.jar
commons-logging-1.1.jar
cxf-2.0-incubator.jar
geronimo-activation_1.1_spec-1.0-M1.jar (or Sun’s Activation jar)
geronimo-annotation_1.0_spec-1.1.jar (JSR 250)
geronimo-javamail_1.4_spec-1.0-M1.jar (or Sun’s JavaMail jar)
geronimo-servlet_2.5_spec-1.1-M1.jar (or Sun’s Servlet jar)
geronimo-ws-metadata_2.0_spec-1.1.1.jar (JSR 181)
jaxb-api-2.0.jar
jaxb-impl-2.0.5.jar
jaxws-api-2.0.jar
jetty-6.1.5.jar
jetty-util-6.1.5.jar
neethi-2.0.jar
saaj-api-1.3.jar
saaj-impl-1.3.jar
spring-core-2.0.4.jar
spring-beans-2.0.4.jar
spring-context-2.0.4.jar
spring-web-2.0.4.jar
stax-api-1.0.1.jar
wsdl4j-1.6.1.jar
wstx-asl-3.2.1.jar
XmlSchema-1.2.jar
xml-resolver-1.2.jar

The first thing which needed to be done was to create the service interface. The service interface defines which methods the web service client will be able to call. It’s pretty standard Java with just two JWS (Java Web Service) annotations thrown in:

package com.company.auth.service;

import javax.jws.WebService;
import javax.jws.WebParam;
import com.company.auth.bean.Employee;

@WebService
public interface AuthService {
Employee getEmployee(@WebParam(name="gid") String gid);
}

The @WebParam annotation is in fact optional, but highly recommended since it will make like easier for the end consumers of your service. Without it, your parameter would be named arg0 making it less clear what parameters your service actually takes.

Implementing the actual service comes next:

package com.company.auth.service;

import javax.jws.WebService;

import com.company.auth.bean.Employee;
import com.company.auth.dao.EmployeeDAO;

@WebService(endpointInterface = "com.company.auth.service.AuthService", serviceName = "corporateAuthService")
public class AuthServiceImpl implements AuthService {

public Employee getEmployee(String gid) {
EmployeeDAO dao = new EmployeeDAO();
return dao.getEmployee(gid);
}

}

I then had to tell Spring (which is used by CXF) where to find my Java classes. I created the following cxf.xml file inside my package directory (com/company/auth/service):

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://cxf.apache.org/jaxws

  http://cxf.apache.org/schemas/jaxws.xsd">

<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxws:endpoint id="auth"
implementor="com.company.auth.service.AuthServiceImpl"
address="/cxfAuth"/>
</beans>

Finally, I updated my WEB-INF/web.xml file to let CXF know where my cxf.xml file was and define the CXF servlet:
<?xml version="1.0"?>
<!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>Auth Manager</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:com/company/auth/service/cxf.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>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>

The final step is to build the client. This was very easy when compared to getting the server up and running because I was able to simply swipe the code from the Apache CXF documentation. So, without further ado:

package com.company.auth.client;

import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

import com.company.auth.bean.Employee;
import com.company.auth.service.AuthService;

public final class Client {

private Client() {
}

public static void main(String args[]) throws Exception {

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();

factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
factory.setServiceClass(AuthService.class);
factory.setAddress("http://localhost:7001/authManager/services/cxfAuth");
AuthService client = (AuthService) factory.create();

Employee employee = client.getEmployee("0223938");
System.out.println("Server said: " + employee.getLastName() + ", " + employee.getFirstName());
System.exit(0);

}

}

No comments:

Post a Comment