使用CXF釋出WebService服務簡單例項
一、說明:
前面介紹了使用axis2來發布Webservice服務,現在介紹一種更popular,更高效的Webservice服務釋出技術:CXF
Apache CXF = Celtix + XFire,Apache CXF 的前身叫 Apache CeltiXfire,現在已經正式更名為 Apache CXF 了,以下簡稱為 CXF。CXF 繼承了 Celtix 和 XFire 兩大開源專案的精華,提供了對 JAX-WS 全面的支援,並且提供了多種 Binding 、DataBinding、Transport 以及各種 Format 的支援,並且可以根據實際專案的需要,採用程式碼優先(Code First)或者 WSDL 優先(WSDL First)來輕鬆地實現 Web Services 的釋出和使用。目前它仍只是 Apache 的一個孵化專案。
Apache CXF 是一個開源的 Services 框架,CXF 幫助您利用 Frontend 程式設計 API 來構建和開發 Services ,像 JAX-WS 。這些 Services 可以支援多種協議,比如:SOAP、XML/HTTP、RESTful HTTP 或者 CORBA ,並且可以在多種傳輸協議上執行,比如:HTTP、JMS 或者 JBI,CXF 大大簡化了 Services 的建立,同時它繼承了 XFire 傳統,一樣可以天然地和 Spring 進行無縫整合。
CXF 框架是一種基於 Servlet 技術的 SOA 應用開發框架,要正常執行基於 CXF 應用框架開發的企業應用,除了 CXF 框架本身之外,還需要 JDK 和 Servlet 容器的支援。
二、利用CXF進行簡單webservice服務的釋出與呼叫
①. 新建一個Java Project ,CXFDemo ,並在工程下新建lib資料夾,加入CXF的jar包:
cxf-core-3.1.4.jar
jaxb-core-2.2.11.jar
jaxb-impl-2.2.11.jar
neethi-3.0.3.jar
wsdl4j-1.6.3.jar
xmlschema-core-2.2.1.jar
然後build path ,將架包加入到類路徑下。
②. 在src下,新建3個package ,並分別在各個包下建立對應的相關介面和類:
com.elgin.cxf.entities
com.elgin.cxf.service
com.elgin.cxf.service.impl
❶、在service包下新建介面 HelloService
package com.elgin.cxf.service;
import javax.jws.WebParam;
import javax.jws.WebService;
import com.elgin.cxf.entities.User;
@WebService
public interface HelloService {
public String sayHello(@WebParam(name="text")String text);
public String sayHellloToUser(User user);
}
❷、在service.impl 包下新建介面的實現類 HelloServiceImpl
package com.elgin.cxf.service.impl;
import javax.jws.WebService;
import com.elgin.cxf.entities.User;
import com.elgin.cxf.service.HelloService;
@WebService(endpointInterface="com.elgin.cxf.service.HelloService",serviceName="HelloService")
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String text) {
System.out.println("param text is :" + text);
return "hello " + text;
}
@Override
public String sayHellloToUser(User user) {
System.out.println("param user is :" +user);
return "hello " + user.getName();
}
}
❸、entities包下新建用到的User類:
package com.elgin.cxf.entities;
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User(){}
public User(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "User [name=" + name + "]";
}
}
③. 新建package :com.elgin.cxf.publish
並在此包下新建類: Server 用來發布webservice服務:
package com.elgin.cxf.publish;
import javax.xml.ws.Endpoint;
import com.elgin.cxf.service.impl.HelloServiceImpl;
public class Server {
public static void main(String[] args) {
System.out.println("cxf service start..");
HelloServiceImpl serviceImpl=new HelloServiceImpl();
String address="http://localhost:8080/service/hello";
Endpoint.publish(address, serviceImpl);
}
}
④ 執行檢視釋出情況:
在瀏覽器輸入:http://localhost:8080/service/hello?wsdl ,出現下圖所示資料,表示釋出webservice服務成功
⑤ 服務呼叫程式碼以及結果:
package com.elgin.cxf.client;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;
import com.elgin.cxf.entities.User;
import com.elgin.cxf.service.HelloService;
public class Client {
private static final QName SERVICE_NAME
= new QName("http://impl.service.cxf.elgin.com/", "HelloService");
private static final QName PORT_NAME
= new QName("http://impl.service.cxf.elgin.com/", "HelloServicePort");
private Client() {}
public static void main(String args[]) throws Exception {
rightInvoker();
exceptionInvoker();
}
/*
* @Title: rightInvoker
* @Description: 可成功呼叫,返回正確的結果
* @throws Exception 引數
*/
public static void rightInvoker() throws Exception {
// Endpoint Address
String endpointAddress = "http://localhost:8080/service/hello";
URL url=new URL(endpointAddress);
Service service = Service.create(url,SERVICE_NAME);
HelloService hs = service.getPort(HelloService.class);
System.out.println(hs.sayHello("World"));
User user = new User("Jack");
System.out.println(hs.sayHellloToUser(user));
}
/*
* @Title: exceptionInvoker
* @Description: 呼叫時出現異常錯誤資訊:
*
* Exception in thread "main" javax.xml.ws.WebServiceException:
* WSDL Metadata not available to create the proxy,
* either Service instance or ServiceEndpointInterface com.elgin.cxf.service.HelloService should have WSDL information
*
* 對於造成上述異常的具體原因尚不明確,很有可能是缺少CXF某個jar包引起
*/
public static void exceptionInvoker(){
// Endpoint Address
Service service = Service.create(SERVICE_NAME);
String endpointAddress = "http://localhost:8080/service/hello";
service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);
HelloService hs = service.getPort(HelloService.class);
System.out.println(hs.sayHello("World"));
User user = new User("Jack");
System.out.println(hs.sayHellloToUser(user));
}
}
正確執行結果:
hello World
hello Jack