使用apache CXF开发第一个Web服务

09-08-30 banq
Tutorial to develop Contract First webservice using CXF

我们要使用apache CXF完成下面这个Web服务:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="EmpWorkHours" targetNamespace="http://ts.com/empwork"    xmlns:tns="http://ts.com/empwork"    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"    xmlns="http://schemas.xmlsoap.org/wsdl/"    xmlns:emp="http://ts.com/empwork/types"    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <wsdl:types>
        <schema targetNamespace="http://ts.com/empwork/types"   xmlns="http://www.w3.org/2001/XMLSchema"       xmlns:tns="http://ts.com/empwork/types"          elementFormDefault="qualified">
            <xsd:element name="EmpWorkHoursRequest" type="emp:EmpWorkHoursRequestType"/>
            <xsd:element name="EmpWorkHoursResponse" type="emp:EmpWorkHoursResultType"/>
            <xsd:complexType name="EmpWorkHoursRequestType">
                <xsd:sequence>
                    <xsd:element name="empid" type="xsd:string"/>
                    <xsd:element name="year" type="xsd:integer"/>
                </xsd:sequence>
            </xsd:complexType>
            <xsd:complexType name="EmpWorkHoursResultType">
                <xsd:sequence>
                    <xsd:element name="empid" type="xsd:string"/>
                    <xsd:element name="year" type="xsd:integer"/>
                    <xsd:element name="name" type="xsd:string"/>
                    <xsd:element name="workhours" type="xsd:integer"/>
                </xsd:sequence>
            </xsd:complexType>
        </schema>
    </wsdl:types>
    <wsdl:message name="request">
        <wsdl:part element="emp:EmpWorkHoursRequest" name="in"/>
    </wsdl:message>
    <wsdl:message name="response">
        <wsdl:part element="emp:EmpWorkHoursResponse" name="out"/>
    </wsdl:message>
    <wsdl:portType name="EmpWorkHours">
        <wsdl:operation name="getWorkHours">
            <wsdl:input message="tns:request" name="workHoursRequest"/>
            <wsdl:output message="tns:response" name="workHoursResponse"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="EmpWorkHours_SOAPBinding" type="tns:EmpWorkHours">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/
http"/>
        <wsdl:operation name="getWorkHours">
            <soap:operation soapAction="" style="document"/>
            <wsdl:input name="workHoursRequest">
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output name="workHoursResponse">
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="SOAPService">
        <wsdl:port binding="tns:EmpWorkHours_SOAPBinding" name="EmpWorkHoursWS">
            <soap:address location="http://localhost:8090/cxfcontractfirstwebapp/services/
EmpWorkHoursWS"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>
<p>

    

banq
2009-08-30 13:31

首先创建一个Maven 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>com.thea</groupId>
    <artifactId>cxfcontractfirstwebapp</artifactId>
    <packaging>war</packaging>
    <version>0.1</version>
    <name>cxfcontractfirstwebapp Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>2.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>2.1.2</version>
        </dependency>
      <!-- Jetty is needed if you're are not using the CXFServlet -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http-jetty</artifactId>
            <version>2.1.2</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>cxfcontractfirstwebapp</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
         <!-- wsdl generator plugin-->
            <plugin>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-codegen-plugin</artifactId>
                <version>2.1.2</version>
                <executions>
                    <execution>
                        <id>generate-sources</id>
                        <phase>generate-sources</phase>
                        <configuration>
                            <sourceRoot>./src/main/java</sourceRoot>
                            <wsdlOptions>
                                <wsdlOption>
                                    <wsdl>E:\javacode\nbcodepart2\cxfcontractfirstwebapp\src\main\wsdl\empworkhours.wsdl</wsdl>
                                    <extraargs>
                                        <extraarg>-server</extraarg>
                                        <extraarg>-impl</extraarg>
                                    </extraargs>
                                </wsdlOption>
                            </wsdlOptions>
                        </configuration>
                        <goals>
                            <goal>wsdl2java</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
<p>

在我们的Javaf服务类上加上CXF的元注解 Annotation:

package com.ts.empwork;
import java.math.BigInteger;
import java.util.logging.Logger;
<p>[b]@javax.jws.WebService(serviceName = "SOAPService",
portName = "EmpWorkHoursWS",
targetNamespace = "http://ts.com/empwork",
wsdlLocation = "file:/E:/javacode/nbcodepart2/cxfcontractfirstwebapp/src/main/wsdl/
empworkhours.wsdl",
endpointInterface = "com.ts.empwork.EmpWorkHours")[/b]
public class EmpWorkHoursImpl implements EmpWorkHours {
    private static final Logger LOG =
Logger.getLogger(EmpWorkHoursImpl.class.getName());

    //业务方法代码
    public com.ts.empwork.types.EmpWorkHoursResultType
getWorkHours(com.ts.empwork.types.EmpWorkHoursRequestType in) {
       LOG.info("Executing operation getWorkHours");
       System.out.println(in);
       try {
          com.ts.empwork.types.EmpWorkHoursResultType _return = new
com.ts.empwork.types.EmpWorkHoursResultType();
          //The below data will be fetched from a datasource. To keep the example simple
          //we set hard coded values here
          _return.setEmpid(in.getEmpid());
          _return.setYear(in.getYear());
          _return.setName("Karthik");
          _return.setWorkhours(new BigInteger("1800"));
          return _return;
       } catch (Exception ex) {
          ex.printStackTrace();
          throw new RuntimeException(ex);
       }
    }
}
<p>

使用Maven编译后将产生客户端和服务器端的Web服务代码和配置。

banq
2009-08-30 13:32
CXF和Spring能够无缝结合在一起(所谓无缝其实也是CXF因为在Spring后面出来,为其做了一个转换,如果CXF

在Spring前面出来,然后不需CXF添加新配置和功能,就和Spring整合在一起,这才叫无侵入性的无缝整合,让

别人为你做特别接口,就是你侵入了别人,大家都依赖JVM才是最大的公平和松耦合和无侵入性)

配置Web.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/
javaee/web-app_2_5.xsd">
    <display-name>cxfcontractfirstwebapp</display-name>
    <context-param>
       <param-name>contextConfigLocation</param-name>
      <param-value>classpath: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>
<p>

在Maven的 projectroot/src/main/resources目录下创建一个Spring的CXF.xml配置:

<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="EmpWorkHours"

implementor="com.ts.empwork.EmpWorkHoursImpl"

address="/EmpWorkHoursWS">

<jaxws:properties>

</jaxws:properties>

</jaxws:endpoint>

</beans>

部署到Web服务器中,访问 http://localhost:8090/cxfcontractfirstwebapp/services。

个人评价:回想起2006年我们就能够用JBuilder可视化开发工具拖拉一个POJO服务,JBuilder就为我们生成Web服务的配置。

多么简单,敢情开源社区折腾这么多年,添加了apache CXF 以及Spring,和Maven,只是重走了一篇回头路,

好像还没有原来的方便,NetBeans还是提供这个可视化拖拉功能,可惜依赖它的glassfish,再次为JBuilder消失惋惜啊,

用户在工业界和开源社区之间少了一个中间选择。

[该贴被banq于2009-08-30 13:32修改过]

猜你喜欢