術語
- deal
SEI:Service Endpoint Interface
JAX:Java API for XML Web Servcie
JAX-WS RI:JAX-WS Reference Implementation
UDDI :Universal Description,Discovery and Integration
SOAP:Simple Object Access Protocol
WSDL:Web Services Description Language
SOA :Service Oriented Architecture ,中文一般了解為面向服務的架構,
JAXB : java xml binding, 是jax-rs jax-ws底層使用的對象與xml之間轉換的工具
CXF :基于C#的SOA架構
WCF : 基于java的SOA架構
Web Service: 實作業務訴求
WSDL: 描述如何來使用SOAP 來調用Web 服務的, 通過 http://localhost:8080/webname/servicename?wsdl檢視web服務說明。
SOAP: 簡單對象通路協定,簡單對象通路協定(SOAP)是一種輕量的、簡單的、基于 XML 的協定,它被設計成在 WEB 上交換結構化的和固化的資訊。接口規範
UDDI : 就是一個目錄,隻不過在這個目錄中存放的是一些關于 Web 服務的資訊而已
WebServices的特點:
1、WebServices 是自包含的。即在用戶端不需要附加任何軟體,隻要客戶機支援 HTTP 和XML 就 OK 了。
2、WebServices 是自我描述的。在用戶端和服務端都不需要知道除了請求和響應消息的格式和内容外的任何事。
3、WebServices 是跨平台和跨語言的。用戶端和服務端均可以在不同的平台和語言環境中實作,同時,不必為了支援 WebServices 而更改現有的代碼。
4、WebServices 是基于開放和标準的。XML 和 HTTP 是WebServices 的主要技術基礎,而 XML 和HTTP 早就成了業内标準了。
5、WebServices 是動态的。
6、WebServices 是可以組合的。也就是通過一個 WebService 通路另外一個 WebService 來達到組合的目的。通過組合 WebServices 便可以将簡單的 WebServices 聚合成為實作更多複雜功能的複雜的服務。
7、WebServices 是松散耦合的。它完全解耦了用戶端和服務端。
8、WebServices 提供程式設計通路的能力。換句話說,就是可以通過編寫程式來通路Web 服務。
9、WebServices 是基于經過考驗的成熟技術上建構的。比如 XML 和 HTTP。
10、WebServices 提供打包現有應用程式的能力。
11、WebServices 通過網絡進行釋出,查找和使用。
JAX-WS與JAX-RS差別是什麼?
**JAX-WS:全稱是JavaTM API forXML-Based Web Services
JAX-RS : 全稱是 JavaTM API forRESTful Web Services**
一、JAX-WS與JAX-RS兩者是不同風格的SOA架構。JAX-WS是針對WebService。而JAX-RS是針對RESTful HTTP Service。
二、JAX-WS以動詞為中心,指定的是每次執行函數。JAX-RS名詞為中心,每次執行的時候指的是資源。
三、JAX-WS面向消息的,每次請求的時候指定了請求的方法。 JAX-RS是面向資源的,每次請求都是對該資源進行操作,比如對資源的增删查改。
四、JAX-RS是JAVA EE6 引入的一個新技術。 JAX-RS是一個Java 程式設計語言的應用程式接口,支援按照表述性狀态轉移(REST)架構風格建立Web服務。
JAX-RS使用了Java SE5引入的Java标注來簡化Web服務的用戶端和服務端的開發和部署。
JAX-WS規範是一組XML web services的JAVA API,JAX-WS允許開發者可以選擇RPC-oriented或者message-oriented 來實作自己的web services。
五、支援JAX-WS服務規範的架構有:CXF,Axis,Xfire。
支援JAX-RS服務規範的架構有:
CXF ——XFire和Celtix的合并
Jersey ——Sun公司的JAX-RS參考實作。
RESTEasy ——JBoss的JAX-RS項目。
Restlet——也許是最早的REST架構了,它JAX-RS之前就有了。
建立 Web Service方式
JAX-WS 2.0有兩種建立Web Service的開發過程:自頂向下和自底向上。自頂向下方式指通過一個WSDL檔案來建立Web Service;自底向上是從Java類出發建立Web Service。
自頂向下:
1、SEI(對應WSDL中的一個Web Service port,在Java中表現為一個接口);
2、SEI實作類;
3、WSDL和XSD檔案;
自底向上:
1、聲明某個類為@WebService,即将它聲明為SEI實作類,然後對需要暴露的方法标注為@WebMethod;
2、運作wsgen指令生成其他所需檔案;
3、釋出Web Service;
注解說明
@javax.jws.WebService
該注解應用于類或者接口上面,該類便是一個對外通路WebService,預設情況裡面所有的public方法都是可以對外提供通路,如果@WebServcie标注接口,那麼該接口有一個專業名稱SEI(ServiceEnpointInterface),該注解的屬性如下:
name : 服務實作類的名稱,wsdl上面 的名稱
serviceName : 服務名稱,wdsl上面的名稱,預設值為 Java 類的簡單名稱 + Service
portName: wsdl上面的名稱,預設為釋出實作者+Port
targetNamespace: 命名空間名稱:釋出webService服務的命名空間,此名稱預設為包路徑的“倒寫”
endpointInterface : 服務接口全路徑, 指定做SEI(Service EndPoint Interface)服務端點接口
wsdlLocation: 指定用于定義 Web Service 的 WSDL 文檔的 Web 位址。Web 位址可以是相對路徑或絕對路徑。
@javax.jws.WebMethod
該注解應用于方法上面,該注解的屬性如下所示:
operationName: 指定與此方法相比對的的名稱。預設值為 Java 方法的名稱
operationName : 定義此操作的行為。對于 SOAP 綁定,此值将确定 頭的值。預設值為 Java 方法的名稱。
exclude: 指定是否從 Web Service 中排除某一方法。預設值為 false。
@javax.jws.Oneway
該注解應用于方法上
注釋将一個方法表示為隻有輸入消息而沒有輸出消息的 Web Service 單向操作。
将此注釋應用于客戶機或伺服器服務端點接口(SEI)上的方法,或者應用于 JavaBeans 端點的伺服器端點實作類
@javax.jws.WebParam
注釋用于定制從單個參數至 Web Service 消息部件和 XML 元素的映射。
将此注釋應用于客戶機或伺服器服務端點接口(SEI)上的方法,或者應用于 JavaBeans 端點的伺服器端點實作類;該注解屬性如下所示:
name: 參數的名稱。如果操作是遠端過程調用(RPC)類型并且未指定partName屬性,那麼這是用于表示參數的 wsdl:part 屬性的名稱。如果操作是文檔類型或者參數映射至某個頭,那麼 -name 是用于表示該參數的 XML 元素的局部名稱。如果操作是文檔類型、參數類型為 BARE 并且方式為 OUT 或 INOUT,那麼必須指定此屬性。
partName: 定義用于表示此參數的 wsdl:part屬性的名稱。僅當操作類型為 RPC 或者操作是文檔類型并且參數類型為BARE 時才使用此參數
targetNamespace : 指定參數的 XML 元素的 XML 名稱空間。當屬性映射至 XML 元素時,僅應用于文檔綁定。預設值為 Web Service 的 targetNamespace。
mode : 此值表示此方法的參數流的方向。有效值為 IN、INOUT 和 OUT。
header : 指定參數是在消息頭還是消息體中。預設值為 false。
@javax.jws.WebResult
注釋用于定制傳回值至 WSDL 部件或 XML 元素的映射。
将此注釋應用于客戶機或伺服器服務端點接口(SEI)上的方法,或者應用于 JavaBeans 端點的伺服器端點實作類。該注解的屬性如下:
name : 當傳回值列示在 WSDL 檔案中并且在連接配接上的消息中找到該傳回值時,指定該傳回值的名稱。對于 RPC 綁定,這是用于表示傳回值的 wsdl:part屬性的名稱。對于文檔綁定,-name參數是用于表示傳回值的 XML 元素的局部名。對于 RPC 和 DOCUMENT/WRAPPED 綁定,預設值為 return。對于 DOCUMENT/BARE 綁定,預設值為方法名 + Response。
targetNamespace : 指定傳回值的 XML 名稱空間。僅當操作類型為 RPC 或者操作是文檔類型并且參數類型為 BARE 時才使用此參數
header : 指定頭中是否附帶結果。預設值為false
partName : 指定 RPC 或 DOCUMENT/BARE 操作的結果的部件名稱。預設值為@WebResult.name
@javax.jws.SOAPBinding
注釋指定 Web Service 與 SOAP 消息協定之間的映射。
将此注釋應用于客戶機或伺服器服務端點接口(SEI)上的類型或方法,或者應用于 JavaBeans 端點的伺服器端點實作類。
方法級别的注釋僅限于它可以指定的對象,僅當style 屬性為 DOCUMENT 時才使用該注釋。如果未指定方法級别的注釋,那麼将使用類型的@SOAPBinding 行為,該注解的屬性如下所示:
style : 定義發送至 Web Service 和來自 Web Service 的消息的編碼樣式。有效值為DOCUMENT 和 RPC。預設值為DOCUMENT。
use : 定義用于發送至 Web Service 和來自 Web Service 的消息的格式。預設值為 LITERAL。ENCODED 在 Feature Pack for Web Services 中不受支援。
parameterStyle : 确定方法的參數是否表示整個消息體,或者參數是否是封裝在執行操作之後命名的頂級元素中的元素。有效值為 WRAPPED 或 BARE。對于DOCUMENT 類型的綁定隻能使用BARE 值。預設值為 WRAPPED。
Demo目錄視圖
Calculator.java
package ws.test.service;
import javax.jws.WebService;
@WebService
public interface Calculator {
public int add(int a, int b);
public int multi(int a, int b);
}
CalculatorImpl.java
package ws.test.service.impl;
import javax.jws.WebService;
import ws.test.service.Calculator;
/**
* 這裡WebService annotation裡加了一個參數"endpointInterface",這個參數用來指定這個WebService的抽象服務接口,
* 例如此處如果不用"endpointInterface"指定接口,那麼生成的WebService服務有三個操作"add","multi"和"minus",也就是定義在目前類中的方法集;
* 如果指定了endpointInterface,則隻有"add","multi",即定義在Calculator中的方法集。
*
*/
@WebService(endpointInterface = "ws.test.service.Calculator")
public class CalculatorImpl implements Calculator {
@Override
public int add(int a, int b) {
return a+b;
}
@Override
public int multi(int a, int b) {
return a*b;
}
public int minus(int a, int b) {
return a - b;
}
}
Endpoint釋出服務
Server.java
import javax.xml.ws.Endpoint;
import ws.test.service.Calculator;
import ws.test.service.impl.CalculatorImpl;
public class Server {
public static void main(String[] args) {
// 部署方式一:
Endpoint.publish("http://localhost:8888/calculator", new CalculatorImpl());
}
}
浏覽器通路:http://localhost:8888/calculator?wsdl
輸入内容如下,部署成功:
通路http://localhost:8888/calculator?wsdl=1, 檢視Calculator 接口說明。
web 容器釋出服務
以Tomcat為例,首先編寫sun-jaxws.xml檔案并放到WEB-INF下
sun-jaxws.xml
<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
version="2.0">
<endpoint name="catculatorImpl"
implementation="ws.test.service.impl.CalculatorImpl"
url-pattern="/ws/catculator" />
</endpoints>
web.xml, 添加listener和servlet(url-pattern要相同哦):
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<listener>
<listener-class>
com.sun.xml.ws.transport.http.servlet.WSServletContextListener
</listener-class>
</listener>
<servlet>
<servlet-name>MyService</servlet-name>
<servlet-class>
com.sun.xml.ws.transport.http.servlet.WSServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyService</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
</web-app>
将下面的jar包放入工程的WEB-INF/lib下
把工程導入tomcat,啟動tomcat。
浏覽器通路http://localhost:8080/ws/ws/catculator,如下圖,部署成功。
通路http://localhost:8080/ws/ws/catculator?wsdl或者http://localhost:8080/ws/ws/catculator?wsdl=1可以看到相關接口說明。
用戶端通路Service:
方法一,不需要生成用戶端代碼,客人比較喜歡這種方式:
Client.java
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import ws.test.service.Calculator;
public class Client {
public static void main(String[] args) throws Exception {
QName qName = new QName("http://impl.service.test.ws/", "CalculatorImplService");
URL url = new URL("http://localhost:8888/calculator?wsdl");
Service service = Service.create(url, qName);
Calculator calculator = service.getPort(Calculator.class);
System.out.println(calculator.add(, ));
}
}
方法二(wsimport生成用戶端):
将上訴代碼複制到你的用戶端項目裡,使用下面的代碼進行通路:
CalculatorImplService service = new CalculatorImplService();
Calculator calculator = service.getPortName();
System.out.println(calculator.add(, ));
方法三(建立一個Web Service Client的項目):
1、建立Web Service Client的項目
2、配置wsdl位址,并點選完成
使用下面的代碼進行通路:
CalculatorImplService service = new CalculatorImplService();
Calculator calculator = service.getPortName();
System.out.println(calculator.add(, ));
這裡有幾點需要說明:
1、getPort()方法的參數:這個方法總是需要指定一個serviceEndpointInterface的類對象serviceEndpointInterface類需要加@WebService的annotation
2、serviceEndpointInterface的targetNamespace需要比對對應的portType的namespace。預設是”http://包名/”,必要時需要定義@WebService的targetNamespace屬性加以改變
3、serviceEndpointInterface的name總是需要比對要調用的PortType的name。預設是類名,必要時需要指定@WebService的name屬性加以改變
4、serviceEndpointInterface中需要有對應于要調用的operation的方法定義