一、背景
WebService基本概念
Web Service也叫XML Web Service,WebService是一種可以接收從Internet或者Internet上的其它系統(tǒng)中傳遞過來的請求,輕量級的獨立的通訊技術(shù)。是:通過SOAP在Web上提供的軟件服務(wù),使用WSDL文件進行說明,并通過UDDI進行注冊。
XML:(Extensible Markup Language)擴展型可標記語言。面向短期的臨時數(shù)據(jù)處理、面向萬維網(wǎng)絡(luò),是Soap的基礎(chǔ)。
Soap:(Simple Object Access Protocol)簡單對象存取協(xié)議。是XML Web Service 的通信協(xié)議。當用戶通過UDDI找到你的WSDL描述文檔后,他通過可以SOAP調(diào)用你建立的Web服務(wù)中的一個或多個操作。SOAP是XML文檔形式的調(diào)用方法的規(guī)范,它可以支持不同的底層接口,像HTTP(S)或者SMTP。
WSDL:(Web Services Description Language) WSDL 文件是一個 XML 文檔,用于說明一組 SOAP 消息以及如何交換這些消息。大多數(shù)情況下由軟件自動生成和使用。
UDDI (Universal Description, Discovery, and Integration) 是一個主要針對Web服務(wù)供應商和使用者的新項目。在用戶能夠調(diào)用Web服務(wù)之前,必須確定這個服務(wù)內(nèi)包含哪些商務(wù)方法,找到被調(diào)用的接口定義,還要在服務(wù)端來編制軟件,UDDI是一種根據(jù)描述文檔來引導系統(tǒng)查找相應服務(wù)的機制。UDDI利用SOAP消息機制(標準的XML/HTTP)來發(fā)布,編輯,瀏覽以及查找注冊信息。它采用XML格式來封裝各種不同類型的數(shù)據(jù),并且發(fā)送到注冊中心或者由注冊中心來返回需要的數(shù)據(jù)。
自己按照網(wǎng)上參考搭建了一遍CXF環(huán)境。過程中也有遇到的問題,也做了簡單的整理。
對于CXF是干什么用的,我不想多說,大家都知道這是我們在Java編程中webService技術(shù)的一種實現(xiàn)工具。我們說說為什么用CXF來實現(xiàn)webService:
Java的webService實現(xiàn)本身就是一個很耗性能的實現(xiàn)方案(xml與java對象之間在服務(wù)端以及客戶端的互轉(zhuǎn)比較消耗性能)
目前java主流的webService應用以CXF、AXIS2為主;
通過網(wǎng)絡(luò)渠道的了解,目前CXF的效率要比AXIS2高出至少50%;
另外有一個webService的工具metro的效率比CXF高出10%;
CXF的實現(xiàn)資料網(wǎng)上可以隨便找出一大堆,metro的資料相對少一些;
CXF在java應用實現(xiàn)中已經(jīng)很成熟,企業(yè)更傾向于用這樣一個成熟的解決方案;
基于以上原因,我選擇CXF來實現(xiàn)webService。
二、 以annotation注解方式實現(xiàn)發(fā)布webService應用
首先先建好Web Service工程如下:
下圖是我配置完成后的整個工程目錄,這是我們接下來的目標:
1、 基礎(chǔ)環(huán)境
新建java web工程cxf之后,下載cxf工具包。解壓CXF之后,把cxf工具包lib下的jar包全部放到工程的lib下。
此處用到的cxf工具包版本為:apache-cxf-3.1.12(我選擇的是3.1.12的,大家可以參考,我選擇的是最高版本的)
下載地址:http://cxf.apache.org/download.html
2、 編寫服務(wù)接口
見文件HelloWorld.java
package com.cetc50.server;
import java.util.List;
import javax.jws.WebParam;
import javax.jws.WebService;
import com.cetc50.user.User;
@WebService
public interface HelloWorld {
String sayHi(@WebParam(name="text")String text);
String sayHiToUser(User user);
String[] SayHiToUserList(List<User> userList);
}
3、 服務(wù)接口實現(xiàn)
見文件HelloWorldImpl.java
package com.cetc50.server;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.jws.WebParam;
import javax.jws.WebService;
import com.cetc50.user.User;
@WebService(endpointInterface="com.cetc50.server.HelloWorld",serviceName="HelloWorld")
public class HelloWorldImpl implements HelloWorld {
Map<Integer, User> users = new LinkedHashMap<Integer, User>();
public String sayHi(@WebParam(name = "text") String text) {
return "Hello,"+text;
}
public String sayHiToUser(User user) {
users.put(users.size()+1, user);
return "Hello,"+user.getName();
}
public String[] SayHiToUserList(List<User> userList) {
String[] result = new String[userList.size()];
int i = 0;
for(User u:userList){
result[i] = "Hello " + u.getName();
i++;
}
return result;
}
}
4、 發(fā)布服務(wù)app
見文件webServiceApp.java
package com.cetc50.server;
import javax.xml.ws.Endpoint;
public class webServiceApp {
public static void main(String[] args) {
System.out.println("web service start");
HelloWorldImpl implementor= new HelloWorldImpl();
String address="http://localhost:8080/helloWorld";
Endpoint.publish(address, implementor);
System.out.println("web service started");
}
}
選中webServiceApp.java,右鍵 Run As 選擇Java Application發(fā)布服務(wù);然后在瀏覽器輸入地址:http://localhost:8080/helloWorld?wsdl
出現(xiàn)下圖說明webService服務(wù)發(fā)布成功。
問題來了:
剛開始按照網(wǎng)上參考步驟做了,結(jié)果在發(fā)布時出現(xiàn)如下很長一串英文錯誤:DefaultValidationEventHandler: [ERROR]: prefix wsdp is not bound to a namespace
Location: node: [wsd:Types: null]
解決辦法:經(jīng)過在網(wǎng)上查閱是因為我在引入CXF的jar包時,全加進去了,在lib中找到如下四個jar包,刪除即可。
再次選中webServiceApp.java,右鍵 Run As 選擇Java Application發(fā)布服務(wù);然后在瀏覽器輸入地址:http://localhost:8080/helloWorld?wsdl , 就會露出喜悅的表情,嘿嘿嘿!!!
5、 客戶端訪問服務(wù)
見文件HelloWorldClient.java
package com.cetc50.client;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import com.cetc50.server.HelloWorld;
import com.cetc50.user.User;
public class HelloWorldClient {
public static void main(String[] args) {
//首先右鍵run as 運行com.cetc50.server.webServiceApp類,然后再運行這段客戶端代碼
JaxWsProxyFactoryBean jwpfb = new JaxWsProxyFactoryBean();
jwpfb.setServiceClass(HelloWorld.class);
jwpfb.setAddress("http://localhost:8080/helloWorld");
HelloWorld hw = (HelloWorld) jwpfb.create();
User user = new User();
user.setName("馬克思");
user.setDescription("懷念馬克思");
System.out.println(hw.sayHiToUser(user));
}
}
選中HelloWorldClient.java,右鍵 Run As 選擇Java Application運行,控制臺會打印如下圖:
6、 不能忘記了User.java文件
package com.cetc50.user;
import java.io.Serializable;
@SuppressWarnings("serial")
public class User implements Serializable {
private String id;
private String name;
private String age;
private String description;
public User() {
super();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
此篇實現(xiàn)了webService服務(wù)的發(fā)布以及在本工程下的客戶端調(diào)用服務(wù)的示例并不是很直觀,歡迎學習和指導。
本文參照了:CXF實現(xiàn)webService服務(wù)(一)