1. 程式人生 > >jax-ws入門, 相關名詞釋義

jax-ws入門, 相關名詞釋義

術語

  • 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());
    }
}

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下
這裡寫圖片描述

客戶端訪問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(10, 5));
    }

}

方法二(wsimport生成客戶端):

wsimport -keep http://localhost:8888/calculator?wsdl

這裡寫圖片描述
將上訴程式碼複製到你的客戶端專案裡,使用下面的程式碼進行訪問:

    CalculatorImplService service = new CalculatorImplService();  
    Calculator calculator = service.getPortName();  
    System.out.println(calculator.add(1, 2));  

方法三(建立一個Web Service Client的專案):
1、建立Web Service Client的專案
這裡寫圖片描述
2、配置wsdl地址,並點選完成
這裡寫圖片描述
使用下面的程式碼進行訪問:

    CalculatorImplService service = new CalculatorImplService();  
    Calculator calculator = service.getPortName();  
    System.out.println(calculator.add(1, 2));  

這裡有幾點需要說明:
1、getPort()方法的引數:這個方法總是需要指定一個serviceEndpointInterface的類物件serviceEndpointInterface類需要加@WebService的annotation
2、serviceEndpointInterface的targetNamespace需要匹配對應的portType的namespace。預設是”http://包名/”,必要時需要定義@WebService的targetNamespace屬性加以改變
3、serviceEndpointInterface的name總是需要匹配要呼叫的PortType的name。預設是類名,必要時需要指定@WebService的name屬性加以改變
4、serviceEndpointInterface中需要有對應於要呼叫的operation的方法定義