day45_Webservice學習筆記_01

一、課程安排

Webservice就是一種遠程調用技術,它的作用就是從遠程系統中獲取業務數據。

    客戶端通過網絡通信協議訪問服務端,網絡協議包括TCP和UDP兩大通信協議:
    TCP是一種面向連接的協議,提供可靠的數據傳輸,一般服務質量要求比較高的情況,使用這個協議。
    TCP支持的應用協議主要有:Telnet、FTP、SMTP、HTTP等;
    UDP用戶數據報協議,是一種無連接的傳輸層協議,提供面向事務的簡單不可靠信息傳送服務。
    UDP支持的應用層協議主要有:NFS(網絡文件系統)、SNMP(簡單網絡管理協議)、DNS(主域名稱系統)、TFTP(通用文件傳輸協議)等。
    客戶服務器模式早期主要應用於c/s應用,web興起後主要應用於b/s應用,b/s比c/s的好處就在於b/s是基於瀏覽器客戶端訪問服務端。

課程安排:

  • 什麼是webservice
  • Webservice的入門程序
  • Webservice的應用場景
  • Webservice的三要素
  • WSDL:web服務描述語言
  • SOAP:簡單對象訪問協議
  • UDDI:目錄服務
  • Webservice的四種客戶端調用方式
  • 生成客戶端調用方式
  • 客戶端編程調用方式
  • HttpURLConnection調用方式
  • Ajax調用方式
  • 深入開發:用註解修改WSDL內容

二、什麼是webservice

Web service 即web服務,它是一種跨編程語言和跨操作系統平臺的遠程調用技術即跨平臺遠程調用技術。

2.1、什麼是遠程調用技術?

  • 遠程調用數據定義:是系統和系統之間的調用。 如下圖所示:

2.2、Webservice的原理圖

  • Webservice是使用Http發送SOAP協議的數據的一種遠程調用技術
  • Webservice要開發服務端
  • Webservice要開發客戶端
  • Webservice客戶端開發需要閱讀服務端的使用說明書(WSDL) 如下圖所示:

2.3、Webservice的開發規範

詳解如下:

    JAVA 中共有三種WebService 規範,分別是JAX-WS(JAX-RPC)、JAXM&SAAJ、JAX-RS。
    下面來分別簡要的介紹一下這三個規範。

1、JAX-WS(小公司使用)
    JAX-WS  的全稱爲 Java API for XML-Based Webservices ,早期的基於SOAP 的JAVA 的Web 服務規範JAX-RPC(Java API For XML-Remote Procedure Call),
目前已經被JAX-WS規範取代。從java5開始支持JAX-WS2.0版本,Jdk1.6.0_13以後的版本支持2.1版本,jdk1.7支持2.2版本。

2、JAXM&SAAJ(不常用)
    JAXM(JAVA API For XML Message)主要定義了包含了發送和接收消息所需的API,SAAJ(SOAP With Attachment API For Java,JSR 67)是與JAXM 搭配使用的API,
爲構建SOAP 包和解析SOAP 包提供了重要的支持,支持附件傳輸等,JAXM&SAAJ 與JAX-WS 都是基於SOAP 的Web 服務,相比之下JAXM&SAAJ 暴露了SOAP更多的底層細節,編碼比較麻煩,
而JAX-WS 更加抽象,隱藏了更多的細節,更加面向對象,實現起來你基本上不需要關心SOAP 的任何細節。

3、JAX-RS(大公司使用)
    JAX-RS 是JAVA 針對REST(Representation State Transfer)風格制定的一套Web 服務規範,由於推出的較晚,該規範(JSR 311,目前JAX-RS 的版本爲1.0)並未隨JDK1.6 一起發行。

三、Webservice的入門程序

3.1、需求

  服務端:發佈一個天氣查詢服務,接收客戶端城市名稱,返回天氣數據給客戶端。   客戶端:發送城市名稱給服務端,接收服務端的返回天氣數據,打印出來。

3.2、環境

  JDK:1.8   Eclipse:Oxygen

3.3、實現-服務端

開發步驟: 第一步:創建SEI(Service Endpoint Interface)接口,本質上就是Java接口

package com.itheima.webservice.jaxws.ws;

/*
 * SEI接口
 */
public interface WeatherInterface {

    public String queryWeather(String cityName);
}

第二步:創建SEI實現類,在實現類上加入註解@WebService

package com.itheima.webservice.jaxws.ws;

import javax.jws.WebService;

@WebService  // @WebService表示該類是一個服務類,需要發佈其中的public的方法
public class WeatherInterfaceImpl implements WeatherInterface {

    @Override
    public String queryWeather(String cityName) {
        System.out.println("from client..." + cityName);
        String weather = "晴";
        return weather;
    }

}

第三步:發佈服務,Endpoint發佈服務,publish方法,兩個參數:1.服務地址;2.服務實現類

package com.itheima.webservice.jaxws.ws;

import javax.xml.ws.Endpoint;

public class WeatherServer {
    public static void main(String[] args) {
        // Endpoint 發佈服務
        // 參數解釋:
        //      1.address - 服務地址
        //      2.implementor - 服務實現類
        Endpoint.publish("http://127.0.0.1:12345/weather", new WeatherInterfaceImpl());
    }
}

第四步:測試Webservice服務是否發佈成功,通過閱讀使用說明書,確定客戶端調用的接口、方法、參數和返回值存在,證明服務發佈成功。

  • WSDL地址:服務地址+”?wsdl”
  • WSDL閱讀方式:從下往上閱讀

如下圖所示: 1、

2、

3、

3.4、實現-客戶端

開發步驟:

  • 第一步:wsimport命令生成客戶端代碼 wsimport -s . http://127.0.0.1:12345/weather?wsdl
  • 第二步:根據使用說明書,使用客戶端代碼調用服務端
    • 第一步:創建服務視圖,視圖是從service標籤的name屬性獲取
    • 第二步:獲取服務實現類,實現類從portType標籤的name屬性獲取
    • 第三步:調用查詢方法,從portType的operation標籤的name屬性獲取

示例代碼如下:

package com.itheima.webservice.jaxws.ws.client;

import com.itheima.webservice.jaxws.ws.WeatherInterfaceImpl;
import com.itheima.webservice.jaxws.ws.WeatherInterfaceImplService;

/*
 * 天氣查詢客戶端
 */
public class WeatherClient {

    public static void main(String[] args) {
        // 創建服務視圖
        WeatherInterfaceImplService weatherInterfaceImplService = new WeatherInterfaceImplService();
        // 獲取服務實現類
        WeatherInterfaceImpl weatherInterfaceImpl = weatherInterfaceImplService.getPort(WeatherInterfaceImpl.class);
        // 調用查詢方法,打印
        String weather = weatherInterfaceImpl.queryWeather("北京");

        System.out.println(weather);
    }
}

客戶端效果如下圖所示:

服務端效果如下圖所示:

3.5、Webservice的優缺點

  • 優點:
    • 發送方式採用http的post方式發送,http的默認端口是80,防火牆默認不攔截80,所以跨防火牆。
    • 採用XML格式封裝數據,XML是跨平臺的,所以webservice也可以跨平臺。
    • Webservice支持面向對象。
    • 有利於軟件和數據重用,實現鬆耦合。
  • 缺點:
    • 採用XML格式封裝數據,所以在傳輸過程中,要傳輸額外的標籤,隨着SOAP協議的不斷完善,標籤越來越大,導致webservice的性能下降。

四、Webservice的應用場景

4.1、軟件集成和複用

  • 軟件集成和複用圖解如下:

4.2、適用場景

  • 發佈一個服務(對內/對外),不考慮客戶端類型,不考慮性能,建議使用webservice。比如:便民網站的天氣查詢接口、火車時刻查詢接口等。
  • 服務端已經確定使用webservice,客戶端不能選擇,必須使用webservice。

4.3、不適用場景

  • 考慮性能時不建議使用webservice。比如:銀行交易系統、股票交易系統(炒股時候玩的槓桿(高端用戶))等,任何延遲都可能造成無法估量的損失。
  • 同構程序之間通信(都是用同一種語言開發的)不建議使用webservice。比如:Java的RMI同樣可以實現遠程調用,而且性能比webservice好很多。

五、WSDL

5.1、WSDL的定義

  • WSDL 指網絡服務描述語言(Web Services Description Language)。
  • 它是webservice服務端使用的說明書,說明服務端接口、方法、參數和返回值,WSDL是隨服務發佈成功,自動生成,無需編寫。

5.2、WSDL的文檔結構+閱讀方式

詳解如下:

<service>   服務視圖:webservice的服務結點,它包括了服務端點port(一般會有多個服務端點)。
<binding>   爲每個服務端點port定義消息格式和協議細節。
<portType>  服務端點類型:描述 web service可被執行的操作方法,以及相關的消息,通過binding指向portType。
<message>   定義一個操作(方法)的數據參數(可有多個參數)。
<types>     定義 web service 使用的全部數據類型。

從下往上讀:先找到服務視圖,通過binging找到protType,找到了protType就找到了我們要調用的webservice方法。

WSDL的文檔結構圖以及WSDL的閱讀方式如下圖所示;

六、SOAP

6.1、SOAP的定義

  • SOAP是一種網絡通信協議,即簡易對象訪問協議,它是使用http發送的XML格式的數據,它可以跨平臺,跨防火牆,SOAP不是webservice的專有協議。
  • SOAP = http + xml,其實就是通過HTTP發xml數據。 HTTP請求 與 SOAP請求的區別,如下圖所示:

6.2、SOAP協議的格式

  • 必需有 envelope 元素,此元素將整個 XML 文檔標識爲一條 SOAP 消息。
  • 可選的 header 元素,包含頭部信息。
  • 必需有 body 元素,包含所有的調用和響應信息。
  • 可選的 fault 元素,提供有關在處理此消息所發生錯誤的信息。

6.3、TCP/IP Monitor

  • 我們想看SOAP協議的格式,怎麼辦呢?那就得底層去查看,需要用到一個工具:TCP/IP Monitor,TCP/IP Monitor是一個代理服務器,它可以把服務器和客戶端之間的交互通過代理來實現,然後監控它們之間的交互。

在MyEcplise中如何進行配置呢?步驟如下: Windows --> Show View --> Other…

在搜索框中輸入“tcp”

在小三角處點擊,選擇 Properties

再選擇 Add…,配置解釋如下圖所示:

配置如下圖所示:

在瀏覽器中輸入代理服務地址,能正常訪問,代表代理服務器設置成功,如下圖所示:

修改客戶端代碼,修改的代碼文件是WeatherInterfaceImplService.java,把該代碼裏面所有的端口號12345改爲54321,保存,打開服務端,查看代理服務器是否有作用,如下圖所示,代理服務器起作用了。

有中文亂碼,我們設置一下編碼方式:

6.4、SOAP1.1

請求:

......
POST /weather HTTP/1.1
Accept: text/xml, multipart/related
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://ws.jaxws.webservice.itheima.com/WeatherInterfaceImpl/queryWeatherRequest"
User-Agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e
Host: 127.0.0.1:54321
Connection: keep-alive
Content-Length: 224

<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body><ns2:queryWeather xmlns:ns2="http://ws.jaxws.webservice.itheima.com/">
        <arg0>北京</arg0></ns2:queryWeather>
    </S:Body>
</S:Envelope>

響應:

......
HTTP/1.1 200 OK
Date: Thu, 20 Sep 2018 07:44:22 GMT
Transfer-encoding: chunked
Content-type: text/xml; charset=utf-8

<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body><ns2:queryWeatherResponse xmlns:ns2="http://ws.jaxws.webservice.itheima.com/">
        <return>晴</return></ns2:queryWeatherResponse>
    </S:Body>
</S:Envelope>

6.5、SOAP1.2

  • 如何發佈SOAP1.2服務端
  • jaxws不支持SOAP1.2服務端發佈,直接發佈會報如下異常:
  • 如果想發佈SOAP1.2服務端,需要在服務端引入第三方jar包:jaxws-ri-2.2.8
  • 並在實現類上加入註解:@BindingType(SOAPBinding.SOAP12HTTP_BINDING)

請求:

......
POST /weather HTTP/1.1
Accept: application/soap+xml, multipart/related
Content-Type: application/soap+xml; charset=utf-8;action="http://ws.jaxws.webservice.itheima.com/WeatherInterfaceImpl/queryWeatherRequest"
User-Agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e
Host: 127.0.0.1:54321
Connection: keep-alive
Content-Length: 222

<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
    <S:Body><ns2:queryWeather xmlns:ns2="http://ws.jaxws.webservice.itheima.com/">
        <arg0>北京</arg0></ns2:queryWeather>
    </S:Body>
</S:Envelope>

響應:

......
HTTP/1.1 200 OK
Date: Thu, 20 Sep 2018 09:05:06 GMT
Transfer-encoding: chunked
Content-type: application/soap+xml; charset=utf-8


<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
    <S:Body><ns2:queryWeatherResponse xmlns:ns2="http://ws.jaxws.webservice.itheima.com/">
        <return>晴</return></ns2:queryWeatherResponse>
    </S:Body>
</S:Envelope>

6.6、SOAP1.1和SOAP1.2區別

  • 相同點:
    • 請求發送方式相同:都是使用POST
    • 協議內容相同:都有Envelope和Body標籤
  • 不同點:
    • 數據格式不同:content-type不同
      • SOAP1.1:text/xml; charset=utf-8
      • SOAP1.2:application/soap+xml; charset=utf-8
    • 命名空間不同:
      • SOAP1.1:http://schemas.xmlsoap.org/soap/envelope/
      • SOAP1.2:http://www.w3.org/2003/05/soap-envelope

七、UDDI

  • UDDI 是一種目錄服務,企業可以使用它對 Web services 進行註冊和搜索。UDDI,英文爲 "Universal Description, Discovery and Integration",可譯爲“通用描述、發現與集成服務”。

八、回顧上午所學

什麼是webservice?
    什麼是遠程調用技術?答:系統和系統之間的調用,從遠程系統當中獲取業務數據。
    Webservice是web服務,他是用http傳輸SOAP協議數據的一種遠程調用技術。

Webservice入門程序
    服務端
        第一步:創建SEI接口
        第二步:創建SEI實現類,要在類上加入註解:@WebService,作用是標識這個類是服務類,要發佈裏面的public方法。
        第三步:發佈服務,Endpoint的publish方法,有2兩個參數:1.服務地址 2.實現類實例
        第四步:測試服務是否發佈成功,通過閱讀使用說明書,確定服務接口、方法、參數和返回值存在,說明服務發佈成功。
            WSDL地址:服務地址+”?wsdl”,http://127.0.0.1:54321/weather?wsdl
            WSDL閱讀方式,從下往上,service --> binding --> portType --> 其中有接口、方法、參數和返回值
    客戶端
        第一步:使用wsimport命令生成客戶端代碼
        第二步:根據使用說明書,使用客戶端調用服務端
            創建服務視圖,視圖是從service的name屬性獲取
            獲取服務實現類,從portType的name屬性獲取
            調用查詢方法,從portType下的operation標籤的name屬性獲取
        優缺點:
            優點:發送方式採用http的post,http默認端口是80,所以跨防火牆。
                數據封裝使用XML格式,XML是跨平臺,所以webservice可以跨平臺。
                Webservice支持面向對象開發。
       缺點:使用XML封裝數據,需要額外傳輸其他標籤,性能較差。

Webservice應用場景
    軟件集成和複用
    適用場景:
        發佈服務(對內/對外),不考慮性能,不考慮客戶端類型,建議使用webservice
        服務端已確定使用webservice,客戶端只能使用webservice
    不適用場景:
        考慮性能時,不建議使用webservice
        同構程序下,不建議使用webservice,比如:客戶端服務端都是java開發,建議使用Java RMI,Java的RMI同樣可以實現遠程調用,而且性能比webservice好很多。

WSDL
    定義:WSDL即Web服務描述語言,他是webservice服務端的使用說明書,它說明服務端接口、方法、參數和返回值,它是隨服務發佈成功,自動生成的,無需編寫。
    文檔結構:
        service
        binding
        portType
        message
        types
    閱讀方式:從下往上

SOAP
    定義:SOAP即簡單對象訪問協議,它是使用http發送的XML格式的數據,跨平臺、跨防火牆,它不是webservice的專有協議。
    SOAP = http + xml
    協議的格式:
        必須項:envelope和body
        非必須項:header和fault

SOAP1.1和1.2區別:
    相同點:
        都使用http的POST發送請求
        協議的格式都相同:都有envelope標籤和body標籤
    不同點:
        Content-type數據類選不同:
            SOAP1.1:text/xml; charset=utf-8;
            SOAP1.2: application/soap+xml; charset=utf-8
        命名空間不同:
            SOAP1.1:http://schemas.xmlsoap.org/soap/envelope/
            SOAP1.2:http://www.w3.org/2003/05/soap-envelope

UDDI:就是一個目錄服務,提供搜索和註冊功能,因爲不常用,所以瞭解下就可以了。

九、Webservice的四種客戶端調用方式

公網服務地址:http://www.webxml.com.cn/zh_cn/index.aspx 進入該網站後,--> 點擊 WEB服務 --> 點擊 所需要的WSDL鏈接

9.1、第一種方式:使用默認的實現--創建服務視圖

wsimport命令介紹

wimport就是jdk提供的的一個工具,它的作用是:根據WSDL地址生成客戶端代碼。
wimport位置:D:\learn\Java\JDK\jdk1.8.0_161\bin

wsimport常用的參數:
    -d,生成.class文件的,默認的參數。
    -s,生成.java文件的。
    -p,指定包名的,如果不加該參數,默認包名就是wsdl文檔中的命名空間的倒序。

wsimport僅支持SOAP1.1客戶端的生成。

調用公網手機號歸屬地查詢服務 第一步:在對應的src目錄下,使用wsimport命令生成客戶端代碼 wsimport -p com.itheima.mobile -s . http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl

第二步:閱讀使用說明書,使用生成的客戶端代碼調用服務端,示例代碼如下:

package com.itheima.mobile.client;

import com.itheima.mobile.MobileCodeWS;
import com.itheima.mobile.MobileCodeWSSoap;

/*
 * 公網手機號查詢客戶端
 */
public class MobileClient {

    public static void main(String[] args) {
        // 創建服務視圖
        MobileCodeWS mobileCodeWS = new MobileCodeWS();
        // 獲取服務實現類
        MobileCodeWSSoap mobileCodeWSSoap = mobileCodeWS.getPort(MobileCodeWSSoap.class);
        // 調用查詢方法
        String reuslt = mobileCodeWSSoap.getMobileCodeInfo("1365131", null);

        System.out.println(reuslt);
    }
}

效果截圖如下所示:

調用公網天氣服務端查詢 方法同上 調用公網手機號歸屬地查詢服務 第一步:在對應的src目錄下,使用wsimport命令生成客戶端代碼 wsimport -p com.itheima.weather -s . http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl 但是此時會出現一個錯誤,如下圖所示:

解決方法:WeatherWS.xml另存下來,然後刪除掉標籤:<s:element ref="s:schema" />,然後保存,再次使用wsimport命令生成客戶端代碼,此時不會再報錯了 wsimport -p com.itheima.weather -s . file:///C:\Users\Bruce\Desktop/WeatherWS.xml

第二步:閱讀使用說明書,使用生成的客戶端代碼調用服務端,示例代碼如下:

package com.itheima.weather.client;

import java.util.List;

import com.itheima.weather.ArrayOfString;
import com.itheima.weather.WeatherWS;
import com.itheima.weather.WeatherWSSoap;

public class WeatherClient {

    public static void main(String[] args) {
        // 創建服務視圖
        WeatherWS weatherWS = new WeatherWS();
        // 獲取服務實現類
        WeatherWSSoap weatherWSSoap = weatherWS.getPort(WeatherWSSoap.class);
        // 調用查詢方法
        ArrayOfString arrayOfString = weatherWSSoap.getWeather("北京", "");
        List<String> list = arrayOfString.getString();
        for (String str : list) {
            System.out.println(str);
        }
    }
}

效果截圖如下所示:

第一種生成客戶端調用方式特點: 該種方式使用簡單,但一些關鍵的元素在代碼生成時寫死到生成代碼中,不方便維護,所以僅用於測試。

9.2、第二種方式:使用自己的實現--創建服務視圖

即:service編程調用方式

package com.itheima.mobile.client;

import java.io.IOException;
import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import com.itheima.mobile.MobileCodeWSSoap;

/*
 * service編程實現服務端調用
 */
public class ServiceClient {

    public static void main(String[] args) throws IOException {
        // 創建WSDL的URL,注意:不是服務地址
        URL url = new URL("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl");
        // 創建服務名稱,參數解釋:1、namespaceURI 命名空間地址            2、localPart 服務視圖名稱
        QName qname = new QName("http://WebXml.com.cn/", "MobileCodeWS");
        // 創建服務視圖,參數解釋:1、wsdlDocumentLocation WSDL地址    2、serviceName 服務名稱
        Service service = Service.create(url, qname);
        // 獲取服務實現類
        MobileCodeWSSoap mobileCodeWSSoap = service.getPort(MobileCodeWSSoap.class);
        // 調用查詢方法
        String reuslt = mobileCodeWSSoap.getMobileCodeInfo("13651311090", "");

        System.out.println(reuslt);
    }
}

第二種生成客戶端調用方式特點: 該種方式可以自定義關鍵元素,方便以後維護,是一種標準的開發方式。

9.3、第三種方式:HttpURLConnection調用方式

即:模擬客戶端方式 開發步驟: 第一步:創建服務地址 第二步:打開一個通向服務地址的連接 第三步:設置參數 設置POST,POST必須大寫,如果不大寫,報如下異常:

如果不設置輸入輸出,會報如下異常:

第四步:組織SOAP數據,發送請求 第五步:接收服務端響應,打印 示例代碼如下:

package com.itheima.mobile.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/*
 * HttpURLConnection調用方式實現服務端調用
 */
public class HttpClient {

    public static void main(String[] args) throws IOException {
        // 第一步:創建服務地址,注意:不是WSDL地址
        URL url = new URL("http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx");
        // 第二步:打開一個通向服務地址的連接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        // 第三步:設置參數
        // 設置POST,POST必須大寫,如果不大寫,報如下異常:
        // 3.1、設置發送方式:POST必須大寫
        connection.setRequestMethod("POST");
        // 3.2、設置數據格式:content-type
        connection.setRequestProperty("content-type", "text/xml;charset=utf-8");
        // 3.3、設置輸入輸出:因爲默認新創建的connection沒有讀寫權限
        connection.setDoInput(true);
        connection.setDoOutput(true);
        // 如果不設置輸入輸出,會報如下異常:
        // 第四步:組織SOAP數據,發送請求
        String soapXML = getXML("13651311090");
        OutputStream os = connection.getOutputStream();
        os.write(soapXML.getBytes());
        // 第五步:接收服務端響應,打印
        int responseCode = connection.getResponseCode();
        if (200 == responseCode) { // 表示服務端響應成功
            InputStream is = connection.getInputStream();
            InputStreamReader isr = new InputStreamReader(is); // 由於字節流容易出現亂碼,所以把字節流轉換爲字符流
            BufferedReader br = new BufferedReader(isr); // 爲了高效,裝飾一把,裝飾設計模式

            StringBuilder sb = new StringBuilder();
            String temp = null;
            while (null != (temp = br.readLine())) {
                sb.append(temp);
            }
            System.out.println(sb.toString());
            // 從裏往外關流
            is.close();
            isr.close();
            br.close();
        }
        os.close();
    }

    public static String getXML(String phoneNum) {
        String soapXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" 
        + "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" 
            + "<soap:Body>" 
            + "<getMobileCodeInfo xmlns=\"http://WebXml.com.cn/\">" 
                + "<mobileCode>" + phoneNum + "</mobileCode>" 
              + "<userID></userID>" 
            + "</getMobileCodeInfo>" 
          + "</soap:Body>" 
        + "</soap:Envelope>";
        return soapXML;
    }
}

9.4、第四種方式:Ajax調用方式

示例代碼如下:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script type="text/javascript">
        function queryMobile() {
            // 創建XMLHttpRequest對象
            var xhr = new XMLHttpRequest();
            // 打開連接
            xhr.open("post", "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx", true);
            // 設置數據類型
            xhr.setRequestHeader("content-type", "text/xml;charset=utf-8");
            // 設置回調函數
            xhr.onreadystatechange=function() {
                // 判斷是否發送成功和判斷服務端是否響應成功
                if (4 == xhr.readyState && 200 == xhr.status) {
                    alert(xhr.responseText);
                }
            }
            // 組織SOAP協議數據
            var soapXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
            + "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
                + "<soap:Body>"
                + "<getMobileCodeInfo xmlns=\"http://WebXml.com.cn/\">"
                    + "<mobileCode>" + document.getElementById("phoneNum").value + "</mobileCode>"
                  + "<userID></userID>"
                + "</getMobileCodeInfo>"
              + "</soap:Body>"
            + "</soap:Envelope>";
            alert(soapXML);
            // 發送數據
            xhr.send(soapXML);
        }
    </script>
</head>
<body>
    手機號查詢:<input type="text" id="phoneNum"/> 
    <input type="button" value="查詢" onclick="javascript:queryMobile();"/>
</body>
</html>

十、深入開發:用註解修改WSDL內容

詳解如下:

WebService的註解都位於javax.jws包下:

@WebService-定義服務,在public class 上邊
    targetNamespace:指定命名空間
    name:portType的名稱
    portName:port的名稱
    serviceName:服務名稱
    endpointInterface:SEI接口地址,如果一個服務類實現了多個接口,只需要發佈一個接口的方法,可通過此註解指定要發佈服務的接口。
@WebMethod-定義方法,在公開方法上邊
    operationName:方法名
    exclude:設置爲true表示此方法不是webservice方法,不發佈它;反之則表示webservice方法,默認是false
@WebResult-定義返回值,在方法返回值前邊
    name:返回結果值的名稱
@WebParam-定義參數,在方法參數前邊
    name:指定參數的名稱

作用:
    通過註解,可以更加形像的描述Web服務。對自動生成的wsdl文檔進行修改,爲使用者提供一個更加清晰的wsdl文檔。
    當修改了WebService註解之後,會影響客戶端生成的代碼。調用的方法名和參數名也發生了變化。

示例代碼如下:

package com.itheima.webservice.jaxws.ws;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.xml.ws.soap.SOAPBinding;

@WebService(
        targetNamespace="http://service.cn.itcast",
        name="WeatherWSSoap",
        portName="WeatherWSSoapPort",
        serviceName="WeatherWS"
        ) // @WebService表示該類是一個服務類,需要發佈其中的public的方法
// @BindingType(SOAPBinding.SOAP12HTTP_BINDING)
public class WeatherInterfaceImpl implements WeatherInterface {
    @WebMethod(
            operationName="getWeather",
            exclude=false
            )
    @Override
    public @WebResult(name="result")String queryWeather(@WebParam(name="cityName")String cityName) {
        System.out.println("from client..." + cityName);
        String weather = "晴";
        return weather;
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章