[Tutorial] Create a Web Service with Apache CXF and JBoss 6

转自:http://www.celinio.net/techblog/?p=531

I have recently started studying Apache CXF, the open source web service framework. I am familiar with developing Web Services using EJB 3, Axis or Glue. But not with CXF. Until now.
CXF is a mix of two projects : Celtix and XFire, which explains the name CXF.
It provides support for the JAX-WS, JAX-RS and JAX-RPC specifications.
Developing Web Services using CXF and JBoss is quite easy. The only annoying part is to figure out which JARs libraries
to include in the classpath and which JARs libraries to exclude.

So i am developing a simple web service that calculates the BMI (Body Mass Index). The formula is :
BMI = weight / (height x height)

[b]1)[/b] First create a dynamic web project in Eclipse Helios.
[img]http://dl.iteye.com/upload/attachment/447501/fb224319-4f33-37df-b070-eacf81918353.png[/img]

[b]2)[/b] Download the CXF framework apache-cxf-2.3.1.zip at [url]http://cxf.apache.org/download.html[/url]

[b]3)[/b] After unzipping the archive, I added to WEB-INF/lib all the libraries that are inside the apache-cxf-2.3.1\lib
folder. It is of course not a good habit to have since adding all sorts of libraries can produces conflicts.
I had to remove a few jars such as :
jaxb-xjc-2.2.1.1.jar, xalan-2.7.1.jar and serializer-2.7.1.jar
[img]http://dl.iteye.com/upload/attachment/447504/a2260501-81a6-3c7c-91f0-be7764e8497a.png[/img]

Anyways here is the list of jars that i have added to WEB-INF/lib :

aopalliance-1.0.jar
commons-collections-3.2.1.jar
commons-lang-2.5.jar
commons-logging-1.1.1.jar
commons-pool-1.5.5.jar
cxf-2.3.1.jar
cxf-manifest.jar
cxf-xjc-boolean-2.3.0.jar
cxf-xjc-bug671-2.3.0.jar
cxf-xjc-dv-2.3.0.jar
cxf-xjc-ts-2.3.0.jar
FastInfoset-1.2.8.jar
geronimo-activation_1.1_spec-1.1.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-javamail_1.4_spec-1.7.1.jar
geronimo-jaxws_2.2_spec-1.0.jar
geronimo-jms_1.1_spec-1.1.1.jar
geronimo-servlet_3.0_spec-1.0.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
geronimo-ws-metadata_2.0_spec-1.1.3.jar
jaxb-api-2.2.1.jar
jaxb-impl-2.2.1.1.jar
jettison-1.2.jar
jetty-continuation-7.2.0.v20101020.jar
jetty-http-7.2.0.v20101020.jar
jetty-io-7.2.0.v20101020.jar
jetty-server-7.2.0.v20101020.jar
jetty-util-7.2.0.v20101020.jar
jra-1.0-alpha-4.jar
js-1.7R2.jar
jsr311-api-1.1.1.jar
neethi-2.0.4.jar
saaj-api-1.3.jar
saaj-impl-1.3.2.jar
slf4j-api-1.6.1.jar
slf4j-jdk14-1.6.1.jar
spring-aop-3.0.5.RELEASE.jar
spring-asm-3.0.5.RELEASE.jar
spring-beans-3.0.5.RELEASE.jar
spring-context-3.0.5.RELEASE.jar
spring-core-3.0.5.RELEASE.jar
spring-expression-3.0.5.RELEASE.jar
spring-jms-3.0.5.RELEASE.jar
spring-tx-3.0.5.RELEASE.jar
spring-web-3.0.5.RELEASE.jar
stax2-api-3.0.2.jar
stringtemplate-3.2.jar
velocity-1.6.4.jar
woodstox-core-asl-4.0.8.jar
wsdl4j-1.6.2.jar
wss4j-1.5.10.jar
xml-resolver-1.2.jar
xmlbeans-2.4.0.jar
XmlSchema-1.4.7.jar
xmlsec-1.4.4.jar

There are probably a few extras jars that are not needed but at least they do not produce any error for that simple web service.

[b]4)[/b] Create the Service Endpoint Interface (SEI). Here I use the bottom-up approach (code first) : that is first create a Java class that will be converted into a web service. The other approach is Top-Down (contract first, based on an existing WSDL file).
package com.company.bmi.services;
import javax.jws.WebParam;
import javax.jws.WebService;

@WebService
public interface IBMICalculator {
public double computeBMI(@WebParam(name="weight") double weight, @WebParam(name="height") double height) ;
}



[b]5)[/b] Create the class that implements this interface. It will implement the operations defined by the service :
package com.company.bmi.services;

public class IBMICalculatorImpl implements IBMICalculator{
@Override
public double computeBMI(double weight, double height) {
return weight / (height * height);
}
}

[b]6)[/b] Add the Spring-based configuration file, cxf.xml, under the package directory, for instance :
      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">





implementor="com.company.bmi.services.IBMICalculatorImpl"
address="/cxfBmi"/>


[b]7)[/b] You need to update the deployment descriptor file WEB-INF/web.xml :


BMI

contextConfigLocation
classpath:com/company/bmi/services/cxf.xml




org.springframework.web.context.ContextLoaderListener




CXFServlet

org.apache.cxf.transport.servlet.CXFServlet




CXFServlet
/services/*



I specify the path where to find the cxf.xml file and also the CXFServlet.

[b]8)[/b] Finally create a client that uses this web service. This is a standalone Java class that invokes the IBMICalculator web service :
package com.company.bmi.client;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import com.company.bmi.beans.Person;
import com.company.bmi.services.IBMICalculator;

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(IBMICalculator.class);
factory.setAddress("http://localhost:8085/BMI/services/cxfBmi");
IBMICalculator client = (IBMICalculator) factory.create();
Double bmi = client.computeBMI(75, 170);
System.out.println("BMI : " + bmi);
}
}


[b]9)[/b] The available SOAP services are listed at the following URL :
http://localhost:8085/BMI/services/
[img]http://dl.iteye.com/upload/attachment/447506/c00d1091-c354-390f-900a-8094c4ad659c.png[/img]

[b]10)[/b] WSDL :

http://localhost:8085/BMI/services/cxfBmi?wsdl





















































There is one operation : computeBMI. The input is computeBMI and the output is computeBMIResponse.

[b]11)[/b] The response, displayed when running the client (java code) :

---------------------------
ID: 1
Address: http://localhost:8085/BMI/services/cxfBmi
Encoding: UTF-8
Content-Type: text/xml
Headers: {SOAPAction=[""], Accept=[*/*]}
Payload: 75.0170.0
--------------------------------------
30 janv. 2011 17:56:14 org.apache.cxf.interceptor.AbstractLoggingInterceptor log
INFO: Inbound Message
----------------------------
ID: 1
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml;charset=UTF-8
Headers: {content-type=[text language="/xml;charset=UTF-8"][/text][/text], Date=[Sun, 30 Jan 2011 16:56:14 GMT], Content-Length=[241], X-Powered-By=[Servlet/3.0; JBossAS-6], Server=[Apache-Coyote/1.1]}
Payload: 0.0025951557093425604
--------------------------------------
BMI : 0.0025951557093425604


Another way to test the Web Service is by using soapUI. First create a new SoapUi project (Ctrl+n), give
the project a name and add the WSDL file or URL :

[img]http://dl.iteye.com/upload/attachment/447510/8bc2acc2-5381-3c29-bd50-114f69cbd7e8.png[/img]

Then you need to call the service that you want to test. Double-click the created request “Request 1″ below the computeBMI method. The request editor pops up :

[img]http://dl.iteye.com/upload/attachment/447512/785811d2-66fd-38b9-9d95-b4d8122c8fff.png[/img]

What you need to do next is add values to the parameters of the method. For instance :

75



Then submit the request (green arrow on the top left corner) and validate the response :

0.0025951557093425604


[img]http://dl.iteye.com/upload/attachment/447514/fe13748d-f589-3760-aa97-d6567194259f.png[/img]

你可能感兴趣的:(J2EE)