轉:CXF學習筆記一:如何建立、發布和訪問基於CXF的服務

來源:互聯網
上載者:User
主要參考http://cxf.apache.org的相關內容:

1.使用CXF建立服務的基本方法(使用CXF內建的jetty容器

   參考:http://cxf.apache.org/docs/a-simple-jax-ws-service.html

分4步:

① 設定build環境

② 寫服務

③ 發布服務

④ 訪問服務

1)設定build環境

建立一個新項目,將apache-cxf-2.2.4.zip中lib目錄中的下列檔案添加到Build Path:

commons-logging-1.1.1.jar

geronimo-activation_1.1_spec-1.0.2.jar (or Sun's Activation jar)

geronimo-annotation_1.0_spec-1.1.1.jar (JSR 250)

geronimo-javamail_1.4_spec-1.6.jar (or Sun's JavaMail jar)

geronimo-servlet_2.5_spec-1.2.jar (or Sun's Servlet jar)

geronimo-ws-metadata_2.0_spec-1.1.2.jar (JSR 181)

geronimo-jaxws_2.1_spec-1.0.jar (or Sun's jaxws-api-2.1.jar)

geronimo-stax-api_1.0_spec-1.0.1.jar (or other stax-api jar)

jaxb-api-2.1.jar

jaxb-impl-2.1.12.jar

jetty-6.1.21.jar

jetty-util-6.1.21.jar

neethi-2.0.4.jar

saaj-api-1.3.jar

saaj-impl-1.3.2.jar

wsdl4j-1.6.2.jar

wstx-asl-3.2.8.jar

XmlSchema-1.4.5.jar

xml-resolver-1.2.jar

cxf-2.2.4.jar

可選:添加Spring jars,為XML Configuration添加Spring支援。添加的jars如下:

aopalliance-1.0.jar

spring-core-2.5.5.jar

spring-beans-2.5.5.jar

spring-context-2.5.5.jar

spring-web-2.5.5.jar

2)寫服務

A)寫介面

@WebService

public interface HelloWorld {

String sayHi(String text);

    // JAX-WS/JAXB 不能直接支援進階用例,處理他們需要寫特殊的XmlAdapter

    String sayHiToUser(User user);

    /* Map 傳遞

     * JAXB 不支援 Maps。它能很好的處理Lists,但Maps不能直接支援他們。

     * 他們也需要使用一個XmlAdapter來將maps映射進JAXB可以使用的beans

     */

    @XmlJavaTypeAdapter(IntegerUserMapAdapter.class)

    Map<Integer, User> getUsers();

}

注意:wsdl會重新命名參數的名字,如果不希望這樣,應該這樣寫:

@WebService

public interface HelloWorld {

    String sayHi(@WebParam(name="text") String text);

}

B)寫實現:

package demo.hw.server;

import java.util.LinkedHashMap;

import java.util.Map;

import javax.jws.WebService;

@WebService(endpointInterface = "demo.hw.server.HelloWorld",

            serviceName = "HelloWorld")    //告訴CXF用哪一個介面建立WSDL

public class HelloWorldImpl implements HelloWorld {

    Map<Integer, User> users = new LinkedHashMap<Integer, User>();

    public String sayHi(String text) {

        System.out.println("sayHi called");

        return "Hello " + text;

    }

    public String sayHiToUser(User user) {

        System.out.println("sayHiToUser called");

        users.put(users.size() + 1, user);

        return "Hello "  + user.getName();

    }

    public Map<Integer, User> getUsers() {

        System.out.println("getUsers called");

        return users;

    }

}

3)發布服務(CXF內建Jetty伺服器,所以無需Tomcat就可發布)

A)使用jws的高層封裝:

System.out.println("Starting Server");

HelloWorldImpl implementor = new HelloWorldImpl();

String address = "http://localhost:9000/helloWorld";

Endpoint.publish(address, implementor);

B)使用下列代碼比較精確地控制服務的行為:

HelloWorldImpl implementor = new HelloWorldImpl();

JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();

svrFactory.setServiceClass(HelloWorld.class);   //可省,但不建議,因為可能會有些小問題

svrFactory.setAddress("http://localhost:9000/helloWorld");

svrFactory.setServiceBean(implementor);

svrFactory.getInInterceptors().add(new LoggingInInterceptor());

svrFactory.getOutInterceptors().add(new LoggingOutInterceptor());

svrFactory.create();

自此,可以通過http://localhost:9000/helloWorld?wsdl來顯示該服務的wsdl

LoggingInInterceptor和LoggingOutInterceptor是日誌攔截器,用於輸入和輸出時顯示日誌,下同。

4)訪問服務

A)使用jws的高層封裝:

//第一個參數是介面實作類別包名的反綴

private static final QName SERVICE_NAME = new QName("http://server.hw.demo/", "HelloWorld");

private static final QName PORT_NAME= new QName("http://server.hw.demo/", "HelloWorldPort");

……

Service service = Service.create(SERVICE_NAME);

// Endpoint Address

String endpointAddress = "http://localhost:9000/helloWorld";

// Add a port to the Service

service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);

HelloWorld hw = service.getPort(HelloWorld.class);

System.out.println(hw.sayHi("World"));

B)或者使用下面代碼更精確的控制服務:

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();

factory.getInInterceptors().add(new LoggingInInterceptor());

factory.getOutInterceptors().add(new LoggingOutInterceptor());

factory.setServiceClass(HelloWorld.class);

factory.setAddress("http://localhost:9000/helloWorld");

HelloWorld client = (HelloWorld) factory.create();

String reply = client.sayHi("HI");

System.out.println("Server said: " + reply);

System.exit(0);

2.wsdl2java:從wsdl文檔中產生java類,供client使用

設定環境變數CXF_HOME=D:\Program Files\apache-cxf-2.2.4,PATH後加上“;%CXF_HOME%\bin”(可選),然後執行wsdl2java批次程式,用法如下:
wsdl2java –p 包名 –d 目錄名 wsdl路徑
如:wsdl2java –p demo.service.client –d e:\src htt://localhost:8080/helloWorld?wsdl
-p  指定其wsdl的命名空間,也就是要產生代碼的包名
-d  指定要產生代碼所在目錄
-client 產生用戶端測試web service的代碼
-server 產生伺服器啟動web  service的代碼
-impl 產生web service的實現代碼
-ant  產生build.xml檔案
-all 產生所有開始端點代碼:types,service proxy,,service interface, server mainline, client mainline, implementation object, and an Ant build.xml file.
詳細用法見http://cwiki.apache.org/CXF20DOC/wsdl-to-java.html

3.定義複雜類型(基本類型如int,String,無須額外定義),參考資料:http://cxf.apache.org/docs/defining-contract-first-webservices-with-wsdl-generation-from-java.html

例如:

package com.example.customerservice;

@XmlAccessorType( XmlAccessType.FIELD )

public class Customer {  //自訂類

    String name;

    String\[\] address;

    int numOrders;

    double revenue;

    BigDecimal test;

    Date birthDate;

    CustomerType type; //自訂枚舉類型

}

public enum CustomerType {

    PRIVATE, BUSINESS

}

//定義Exception

@WebFault(name="NoSuchCustomer")

@XmlAccessorType( XmlAccessType.FIELD )

public class NoSuchCustomerException extends RuntimeException {

/**

 * We only define the fault details here. Additionally each fault has a message

 * that should not be defined separately

 */

String customerName;

}     //定義Exceptions的預設行為是在後面產生Java code時建立Exception_Exception,所以必須用@WebFault標記來為Bean取一個名字,以與Exception名字相區別

@WebService    //標記本介面為一個服務

public interface CustomerService {

public Customer[] getCustomersByName(@WebParam(name="name") String name) throws NoSuchCustomerException;     //@WebParam標記wsdl中的參數名。如果省略,wsdl將使用arg0代替

}

// @WebService還可用來自訂介面名和服務名,分別對應:endpointInterface和serviceName,如:

@WebService(endpointInterface = "com.example.customerservice", serviceName = "HelloWorld")

產生的WSDL

<xs:complexType name="customer">  //複雜類型

    <xs:sequence>

        <xs:element minOccurs="0" name="name" type="xs:string"/>

        <xs:element maxOccurs="unbounded" minOccurs="0" name="address" nillable="true" type="xs:string"/>

        <xs:element name="numOrders" type="xs:int"/>

        <xs:element name="revenue" type="xs:double"/>

        <xs:element minOccurs="0" name="test" type="xs:decimal"/>

        <xs:element minOccurs="0" name="birthDate" type="xs:dateTime"/>

        <xs:element minOccurs="0" name="type" type="tns:customerType"/>

    </xs:sequence>

</xs:complexType>

minOccurs="0"是可選項,這樣可以隨時加入新元素,保持相容性。如果不想要這個選項,可以使用標記@XmlElement(required=true)

maxOccurs="unbounded"是為了便於後面的xml重複該元素以形成數組。

<xs:simpleType name="customerType">    //枚舉類型

    <xs:restriction base="xs:string">

        <xs:enumeration value="PRIVATE"/>

        <xs:enumeration value="BUSINESS"/>

    </xs:restriction>

</xs:simpleType>

<xs:element name="NoSuchCustomer" type="tns:NoSuchCustomer"/> //異常類

    <xs:complexType name="NoSuchCustomer">

        <xs:sequence>

            <xs:element name="customerName" nillable="true" type="xs:string"/>

        </xs:sequence>

 </xs:complexType>

 <wsdl:message name="NoSuchCustomerException">

    <wsdl:part name="NoSuchCustomerException" element="tns:NoSuchCustomer">

    </wsdl:part>

 </wsdl:message>

// 注意:Element和Message的名字是不同的,這是通過標記@Webfault標記來實現的。也可以讓他們同名,但那樣會話,產生的Exception的名字會比較醜:NoSuchCustomerException_Exception

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.