目錄
WebService (web服務)概述
1、WebService(Web服務)是一種跨語言、跨平台的遠程調用技術。
A、跨語言:服務器與客戶端可以使用不同的語言開發,客戶端都能調用服務器開放的接口,服務器只需要寫一遍,任意語言的客戶端都能進行調用。 B、跨平台:服務端程序和客戶端程序可以運行在不同的操作系統上。 C、遠程調用:指計算機 A(客戶端) 上的程序可以調用計算機 B(服務器) 上的對象的方法。如火車站進出站需要刷身份證,參加大型展會、演唱會時也可以刷身份證,顯然火車站以及展覽會、演唱會這些刷身份證的系統自己是不可能有全國人民的身份證數據的,它們都在公安局的數據庫里,所以就可以理解成是公安身份證系統使用 webService 向外提供了接口,各地刷身份證的系統作為客戶端調用而已。 |
2、WebService 是可互操作的分布式應用程序的一個平台、一個標准,它定義了應用程序如何在 Web 上實現互操作性,可以用任何語言在任何平台上寫 Web Service 服務端,然后可以通過 Web service 標准對這些服務進行操作。
3、如果系統需要為任意的第三方客戶提供服務,那么服務器系統就可以使用 webService 技術,這樣方便數據交互。需要注意的是如果服務端接口方為webservice,則客戶端也必須使用 webservice 。
web Service 應用場景?
1. 同一家公司的新舊應用之間,子系統之間,如校內的招生系統、就業系統、繳費系統、考試系統等 2. 不同公司的業務應用之間,如天貓網與中通物流系統交互 3. 一些提供數據的內容聚合服務應用,如天氣預報、股票行情、機票、郵政編碼等 |
如何發布一個 webService?
1、定義 SEI(Service Endpoint Interface)服務終端接口,即 webService 提供的服務接口 2、定義 SIB(Service Implemention Bean)服務實現類,即 webService 提供的服務接口的實現類 3、發布 webService 服務 Endpoint publish(String address, Object implementor) |
如何請求一個 webService?
1、根據服務的提供的 wsdl 文檔生成客戶端代碼,可以使用 Java Jdk自帶的 wsimport.exe工具,或者 使用第三方如 Apache 的 CXF wsdl2java 工具既能生成服務端代碼,也能生成客戶端代碼。 2、根據生成的客戶端代碼調用 webService |
一次 web service 請求的本質(流程)?
1、客戶端向服務器端發送了一個 soap消息 (http 請求+ xml 片斷) 2、服務器端處理完請求后, 向客戶端返回一個 soap 消息(結果) 3、整個請求與應答都是圍繞着 wsdl 文件,每次請求都是靠解析 wsdl 文件來確定調用哪個具體的方法,參數以及返回值等,所以如果調用的過程中,如果 wsdl 文件無法訪問,或者文件錯誤,都會導致調用失敗。 |
WebService 平台技術
XML+XSD ,SOAP,WSDL 構成 WebService 平台的三大技術。
1)XML+XSD
WebService 采用 HTTP 協議傳輸數據,采用 XML 格式封裝數據(XML中說明調用遠程服務中哪個對象的方法,傳遞的參數、返回結果等)。XML 的主要優點在於它與平台無關。
XML Schema 語言也稱作 XML Schema 定義(XML Schema Definition,XSD),作用是定義 XML 文檔的合法構建模塊,類似 DTD,最重要的能力之一就是對數據類型的支持。WebService 平台就是用 XSD 來作為其數據類型系統的,當用某種語言(如VB、.NET、C#、Java等)來構造一個 Web service 時,為了符合 WebService 標准,所有使用的數據類型都必須被轉換為XSD類型。
2)SOAP
SOAP(Simple Object Access Protocol)是基於 XML 的簡單對象訪問協議,可使應用程序在 HTTP 之上進行信息交換。
SOAP 指簡易對象訪問協議 SOAP 是一種通信協議 SOAP 用於應用程序之間的通信 SOAP 是一種用於發送消息的格式 SOAP 被設計用來通過因特網進行通信 SOAP 獨立於平台 SOAP 獨立於語言 SOAP 基於 XML SOAP 很簡單並可擴展 SOAP 允許您繞過防火牆 SOAP 將被作為 W3C 標准來發展 |
WebService 通過 HTTP 協議發送請求和接收結果時,發送的請求內容和結果內容都采用XML格式封裝,並增加了一些特定的HTTP 消息頭,以說明 HTTP 消息的內容格式,這些特定的HTTP消息頭和XML內容格式就是SOAP協議。SOAP提供了標准的RPC 方法來調用 Web Service 。
更多 SOAP 可以參考:http://www.w3school.com.cn/soap/index.asp
3)WSDL
WSDL(Web Services Description Language) 是基於 XML web服務描述語言,用於描述 Web Service 及其函數、參數和返回值等,這樣客戶端才能方便調用。一些開發工具既能根據 Web service 生成 WSDL 文檔,又能導入 WSDL 文檔,生成調用相應 WebService 的代理類代碼。
WSDL 文件保存在Web服務器上,通過一個 url 地址即可訪問。客戶端要調用一個WebService服務之前,要知道該服務的WSDL文件的地址,WebService 服務提供商通常通過兩種方式來暴露它的 WSDL 文件地址:1、注冊到UDDI服務器,以便被人查找;2、直接告訴給客戶端調用者。
WebService 工作原理
1、客戶端 API 通過服務器的 wsdl 文件的 url 地址,創建出底層的代理類,客戶端調用這些代理,就可以訪問到 webservice 服務。代理類把客戶端的方法調用變成 soap 格式的請求數據再通過 HTTP 協議發出去,並把接收到的 soap 數據變成返回值返回。
2、對服務端而言,各類 WebService 框架的本質就是一個大大的 Servlet,當遠程客戶端給它通過 http 協議發送過來 soap 格式的請求數據時,它分析這個數據,就知道要調用哪個 java 類的哪個方法,於是去查找或創建這個對象,並調用其方法,再把方法返回的結果包裝成 soap 格式的數據,通過 http 響應消息回給客戶端。
WebService 開發流程
WebService 開發可以分為服務器端開發和客戶端開發兩個方面。
1)服務端開發 | 把公司內部系統的業務方法發布成 WebService 服務,供遠程合作單位和個人調用。 借助一些 WebService 框架可以很輕松地把自己的業務對象發布成 WebService 服務,Java 語言常用的第三方 WebService 框架有:axis,xfire,cxf 等。 當然還以 Java 自己的 JWS 。JWS 是 Java 語言對 WebService 服務的一種實現,用來開發和發布服務,不需要任何第三方庫,為 Java 開發者提供便捷發布和調用 WebService 服務的途徑。 |
2)客戶端開發 | 調用別人發布的 WebService 服務,例如調用天氣預報 WebService 服務、調用門票服務、地圖服務等。 因為是遠程調用服務端的對象方法,所以需要在客戶端也生成服務器提供的服務類,這通常有如下幾種方式: 1、使用第三方如 Apache 的 CXF wsdl2java 工具既能生成服務端代碼,也能生成客戶端代碼; 2、直接使用服務提供商的提供的客戶端編程 API 類; 3、Java JDK 在 bin 目錄下提供了一個 wsimport.exe 程序,用於生成 WebService 客戶端代碼,然后調用 WebService; |
常見 Web Service 框架
1)JWS | JWS 是 Java 語言對 WebService 服務的一種實現,用來開發和發布服務,為 Java 開發者提供便捷發布和調用WebService服務的功能。Java 1.6 開始推出 JWS,在 javax.jws 包下。 |
2)Axis2 | Axis2 是 Apache 中一個重量級 WebService 框架,它是一個 Web Services / SOAP / WSDL 的引擎,是 WebService 框架的集大成者,不但能制作和發布 WebService,而且可以生成 Java 和其它語言版本的 WebService 客戶端和服務端代碼。 它的優勢不可避免的導致了Axis2 的復雜性,所依賴的包數量多,體積大,打包部署發布也比較麻煩,不能很好的與現有應用整合為一體。但是如果是要開發 Java 以外的語言客戶端,Axis2 提供的豐富工具將是不二的選擇。 Axis2 Java 版本官網地址:http://axis.apache.org/axis2/java/core/ |
3)XFire | XFire 是一個高性能的 WebService 框架,在 Java6 之前,它的知名度甚至超過了Apache 的 Axis2,XFire 的優點是開發方便,與現有的 Web 整合很好,可以融為一體,並且開發也很方便。 XFire 對 Java 之外的語言,沒有提供相關的代碼工具,XFire 后來被 Apache 收購了,在此基礎上開發出了更強大的 CXF。 |
4)CXF | 1、CXF(Celtix + XFire) 是 Apache 旗下重磅的 SOA (Service Oriented Architecture) 面向服務的框架,它實現了 ESB(企業服務總線),能很好的和 Spring 進行集成。 2、CXF 由 Celtix 和 XFire 兩個框架合並而來,就像目前的 Struts2 來自 WebWork 一樣。可以看出 XFire 的命運會和 WebWork 的命運一樣,最終會淡出人們的視線。 3、CXF 不但是一個優秀的 Web Services / SOAP / WSDL 引擎,也是一個不錯的 ESB 總線,為 SOA 的實施提供了一種選擇方案。 5、CXF 官網:http://cxf.apache.org/ |
總結:
1、如果應用程序需要多語言的支持,Axis2 應當是首選了;
2、如果應用程序是遵循 Spring 哲學路線的話,Apache CXF 是一種更好的選擇,特別對嵌入式的 Web Services 應用;
3、如果應用程序沒有新的特性需要,項目不大的話,可以任意采用 Axis1,XFire,或者 Java 自帶的 Jws。
JWS(Java Web Service) 概述
1、Java Web Service 是 Java 語言對 WebService 服務的一種實現,用來開發和發布服務,為 Java 開發者提供便捷發布和調用WebService服務的功能。無需借助任何第三方庫。
2、Java 1.6 開始推出 JWS,在 javax.jws 包下,在線 JDK 文檔:https://docs.oracle.com/javase/6/docs/api/。
3、開發過程十分簡單:
1、服務端創建接口 2、服務端創建接口具體實現 3、服務端開啟服務 4、客戶端調用 |
4、編碼也十分簡單,因為整個 javax.jws 包一共也沒多少 API。
5、因為 webservice 以 xml 格式進行傳輸數據,同時也會涉及一些 javax.xml 包下的 API。
JWS(Java Web Service) 快速入門
1、創建一個服務器項目(Java SE)、同時創建一個客戶端項目(Java SE),服務端創建一個接口和其實現類,其中提供數據相加與數據相乘的兩個方法,然后對外提供這個數據計算的服務,客戶端通過 webService 技術可以直接調用服務端系統中的計算方法。
2、無論是 Java SE 應用還是 Java Web 應用,對於使用 jws 的 API 都是一樣的,這里為了簡單以創建 Java SE 項目進行演示。
ws 服務端
新建一個 Java SE 項目如下,名稱 web_server,其中的代碼結構如下。
1、第一步創建 CalculatorService 接口,這是需要對外提供服務的接口,客戶端需要知道其中的內容。 2、第二步創建實現類 CalculatorServiceImpl,這是接口的具體實現,客戶端是無法知道其中的內容的。 3、第三步創建 Web_Service 類,用於啟動 webService 服務。 |
具體的 API 已經在注釋解釋的很詳細了。
1、CalculatorService 接口內容如下:
-
import javax.jws.*;
-
/**
-
* Created by Administrator on 2019/1/25 0025.
-
* 計算器接口
-
* SEI(Service Endpoint Interface):服務終端接口,即webService提供的服務接口
-
* SIB(Service Implemention Bean):服務實現類,即webService提供的服務接口的實現類
-
*
-
* @javax.jws.WebService : 將 Java 類標記為實現 Web Service,或者將 Java 接口標記為定義 Web Service 接口
-
* 不過是服務端還是客戶端,接口上都必須寫上此注解
-
*/
-
@WebService
-
public interface CalculatorService {
-
-
//加法
-
//@WebService 中的方法上可以加上 @WebMethod 注解,也可以不加
-
//@WebMethod 注解寫或不寫,服務端都會將 @WebSerivce 中的所有方法提供給客戶端掉
-
//寫上的好處就是看起來更加直觀而已,如同 @Override 重寫注解意義,刪除也無影響
-
public
float addition(
float a,
float b);
-
-
//乘法
-
public
float multiplication(
float a,
float b);
-
}
2、CalculatorServiceImpl 實現類內容如下:
-
import javax.jws.WebService;
-
import java.util.logging.Logger;
-
/**
-
* Created by Administrator on 2019/1/25 0025.
-
* SEI(Service Endpoint Interface):服務終端接口,即webService提供的服務接口
-
* SIB(Service Implemention Bean):服務實現類,即webService提供的服務接口的實現類
-
*
-
* @javax.jws.WebService : 將 Java 類標記為實現 Web Service,或者將 Java 接口標記為定義 Web Service 接口
-
* endpointInterface:終端接口,定義服務抽象 Web Service 協定的服務端點接口的完整名稱,通常設置為服務實現類的全路徑
-
* 接口要寫,實現類也必須寫 @WebService
-
* @WebService 接口一共提供了以下屬性,而且都有默認值,它們將來都會出現在 wsdl 的 xml 文件中
-
* String name() default
"";
-
* String targetNamespace() default
"";
-
* String serviceName() default
"";
-
* String portName() default
"";
-
* String wsdlLocation() default
"";
-
* String endpointInterface() default
"";
-
*/
-
@WebService(endpointInterface =
"com.lct.web_service.CalculatorService")
-
public class CalculatorServiceImpl implements CalculatorService {
-
//日志記錄器
-
public static final Logger logger = Logger.getGlobal();
-
-
@Override
-
public
float addition(
float a,
float b) {
-
logger.info(
"加法計算:" + a +
" + " + b +
" = " + (a + b));
-
return a + b;
-
}
-
-
@Override
-
public
float multiplication(
float a,
float b) {
-
logger.info(
"乘法計算:" + a +
" x " + b +
" = " + (a * b));
-
return a * b;
-
}
-
}
3、Web_Service 啟動 webService 服務類內容如下:
-
import javax.xml.ws.Endpoint;
-
/**
-
* Created by Administrator on 2019/1/25 0025.
-
* webServer 啟動類
-
*/
-
public class Web_Service {
-
public static void main(String[] args) {
-
/**webService服務器提供給客戶端訪問的地址
-
* 192.168.1.20 為服務器 ip、3333為指定的端口號、web_server 為應用名稱、calculator為標識
-
* 這個地址符合 http 地址即可,為了看起來更像是 web訪問,所以才寫了應用名,其實 http://192.168.1.20:3333/xxx 都是可以的
-
*/
-
String wsUrl =
"http://192.168.1.20:3333/web_server/calculator";
-
-
/**
-
* javax.xml.ws.Endpoint 表示一個 web service 終端,這是一個抽象類,其中提供了靜態方法可以直接調用
-
* Endpoint publish(String address, Object implementor)
-
* address:傳輸協議的 url 地址;
-
* implementor(實現者):web service 終端的實現類,因為一個 ws 接口可能會有多個實現類
-
*/
-
Endpoint.publish(wsUrl, new CalculatorServiceImpl());
-
}
-
}
瀏覽器訪問
1、webService 服務啟動成功之后,根據提供 wsdl 地址,直接通過瀏覽器即可訪問,看到服務端提供的接口(服務),客戶端只需要解析這個 xml 文件即可進行服務調用。
2、注意地址最后的 wsdl 參數必須加上。
此 xml 文件全部內容如下:https://gitee.com/wangmx1993/my-document/blob/master/docs/WebService%20%20WSDL%20%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84.xml
客戶端
1、調用別人發布的 WebService 服務,例如調用天氣預報 WebService 服務、調用門票服務、地圖服務等。因為是遠程調用服務端的對象方法,所以需要在客戶端也生成與服務器一致的服務接口,這通常有如下幾種方式:
1、使用第三方如 Apache 的 CXF wsdl2java 工具既能生成服務端代碼,也能生成客戶端代碼; 2、Java JDK 在 bin 目錄下提供了一個 wsimport.exe 工具,用於根據 wsdl 文件生成 WebService 客戶端代碼,然后調用 WebService; 3、直接使用服務提供商的提供的客戶端編程 API 接口; |
2、簡單的說就是客戶端調用 webService 服務器的接口,客戶端自己也要有與服務器一致的接口,但是客戶端不需要服務端接口的實現類,顯然人家服務提供商自然也不會連實現類都提供出來,再者說,如果連接口和實現都提供了,則遠程調用就沒有意義了,就是再調用自己了。
3、新建客戶端項目(Java SE )如下,其中 CalculatorService 是與服務端一樣的接口,Web_service 類用於調用服務器上的方法。
1、CalculatorService 接口內容如下,如果服務端、客戶端都是 Java 開發,則完全可以聯系服務器開發人員直接把這個接口的代碼發過來即可。所以下面的代碼與服務端完全是一樣的。
-
import javax.jws.WebService;
-
/**
-
* Created by Administrator on 2019/1/25 0025.
-
* 計算器接口
-
* SEI(Service Endpoint Interface):服務終端接口,即webService提供的服務接口
-
* SIB(Service Implemention Bean):服務實現類,即webService提供的服務接口的實現類
-
*
-
* @javax.jws.WebService : 將 Java 類標記為實現 Web Service,或者將 Java 接口標記為定義 Web Service 接口
-
* 無論作為服務端還是客戶端都必須寫 @WebService 注解
-
*/
-
@WebService
-
public interface CalculatorService {
-
-
//加法
-
public
float addition(
float a,
float b);
-
-
//乘法
-
public
float multiplication(
float a,
float b);
-
}
2、Web_service 類用於調用 webService 服務,內容如下:
-
import javax.xml.namespace.QName;
-
import javax.xml.ws.Service;
-
import java.net.MalformedURLException;
-
import java.net.URL;
-
import java.util.logging.Logger;
-
/**
-
* Created by Administrator on 2019/1/25 0025.
-
*/
-
public class Web_service {
-
//日志記錄器
-
public static final Logger logger = Logger.getGlobal();
-
-
public static void main(String[] args) {
-
try {
-
/** url:webservice 服務端提供的服務地址,結尾必須加
"?wsdl"*/
-
URL url = new URL(
"http://192.168.1.20:3333/web_server/calculator?wsdl");
-
-
/** QName 表示 XML 規范中定義的限定名稱,QName 的值包含名稱空間 URI、本地部分和前綴。
-
* QName(final String namespaceURI, final String localPart):指定名稱空間 URI 和本地部分的 QName 構造方法。
-
* 如下所示的兩個數據都可以瀏覽器訪問服務端時返回 xml 中第一行找到,如:
-
* <definitions xmlns:wsu=xxxxxxx targetNamespace=
"http://web_service.lct.com/" name=
"CalculatorServiceImplService">
-
*/
-
QName qName = new QName(
"http://web_service.lct.com/",
"CalculatorServiceImplService");
-
-
/**
-
* Service 對象提供 Web 服務的客戶端視圖
-
* Service 作為以下內容的工廠:1、目標服務端點的代理,2、用於遠程操作的動態面向消息調用的 javax.xml.ws.Dispatch 實例。
-
* create(java.net.URL wsdlDocumentLocation,QName serviceName):創建 Service 實例。
-
* wsdlDocumentLocation : 服務 WSDL 文檔位置的 URL
-
* serviceName : 服務的 QName
-
*/
-
Service service = Service.create(url, qName);
-
-
/**
-
* 使用 getPorts 方法可以對服務上可用的端口/接口進行枚舉
-
* getPort(Class<T> serviceEndpointInterface):獲取支持指定服務端點接口的對象實例
-
* serviceEndpointInterface:指定返回的代理所支持的服務端點接口
-
*/
-
CalculatorService calculatorService = service.getPort(CalculatorService.class);
-
float added = calculatorService.addition(100, 80);
-
float multied = calculatorService.multiplication(2.5F, 100);
-
-
logger.info(
"added:" + added);
-
logger.info(
"multied:" + multied);
-
} catch (MalformedURLException e) {
-
e.printStackTrace();
-
}
-
-
}
-
}
調用測試
1、先運行服務器開啟 webService 服務,然后運行客戶端看是否能調用服務端上的實現類進行計算,如果可以則說明 webService 服務提供成功。
由上可見完全成功。