参考: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)
1、 First create a Web Project in MyEclipse 8.6.
2、Download the CXF framework apache-cxf-2.3.1.zip at http://cxf.apache.org/download.html
3、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
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.
4、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) ; }
5、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); }
6、Add the Spring-based configuration file, cxf.xml, under the package directory, for instance :
<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="calcBMI" implementor="com.company.bmi.services.IBMICalculatorImpl" address="/cxfBmi"/> </beans>
7、You need to update the deployment descriptor file WEB-INF/web.xml :
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>BMI</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:com/company/bmi/services/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>
I specify the path where to find the cxf.xml file and also the CXFServlet.
7、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.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); } }
9、run BMI on Jboss As 6
The available SOAP services are listed at the following URL :
http://localhost:8085/BMI/services/
10、WSDL :
http://localhost:8085/soa_apache_cxf_bmi/services/cxfBmi?wsdl
<wsdl:definitions name="IBMICalculatorImplService" targetNamespace="http://services.bmi.company.com/"> <wsdl:types> <xs:schema elementFormDefault="unqualified" targetNamespace="http://services.bmi.company.com/" version="1.0"> <xs:element name="computeBMI" type="tns:computeBMI"/> <xs:element name="computeBMIResponse" type="tns:computeBMIResponse"/> <xs:complexType name="computeBMI"> <xs:sequence> <xs:element name="weight" type="xs:double"/> <xs:element name="height" type="xs:double"/> </xs:sequence> </xs:complexType> <xs:complexType name="computeBMIResponse"> <xs:sequence> <xs:element name="return" type="xs:double"/> </xs:sequence> </xs:complexType> </xs:schema> </wsdl:types> <wsdl:message name="computeBMIResponse"> <wsdl:part element="tns:computeBMIResponse" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="computeBMI"> <wsdl:part element="tns:computeBMI" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:portType name="IBMICalculator"> <wsdl:operation name="computeBMI"> <wsdl:input message="tns:computeBMI" name="computeBMI"> </wsdl:input> <wsdl:output message="tns:computeBMIResponse" name="computeBMIResponse"> </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="IBMICalculatorImplServiceSoapBinding" type="tns:IBMICalculator"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="computeBMI"> <soap:operation soapAction="" style="document"/> <wsdl:input name="computeBMI"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="computeBMIResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="IBMICalculatorImplService"> <wsdl:port binding="tns:IBMICalculatorImplServiceSoapBinding" name="IBMICalculatorImplPort"> <soap:address location="http://localhost:8085/BMI/services/cxfBmi"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
There is one operation : computeBMI. The input is computeBMI and the output is computeBMIResponse
11、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: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:computeBMI xmlns:ns1="http://services.bmi.company.com/"><weight>75.0</weight><height>170.0</height></ns1:computeBMI></soap:Body></soap:Envelope>
--------------------------------------
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: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:computeBMIResponse xmlns:ns2="http://services.bmi.company.com/"><return>0.0025951557093425604</return></ns2:computeBMIResponse></soap:Body></soap:Envelope>
--------------------------------------
BMI : 0.0025951557093425604