成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

WebService就是這么簡(jiǎn)單

SwordFly / 3212人閱讀

摘要:它使用方式,接收和響應(yīng)外部系統(tǒng)的某種請(qǐng)求?;仡櫸覀?cè)趯W(xué)習(xí)基礎(chǔ)網(wǎng)絡(luò)編程章節(jié)已經(jīng)知道了這么一個(gè)連接了。使用指定名稱的命名空間。名詞簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議作為一個(gè)基于語(yǔ)言的協(xié)議用于有網(wǎng)上傳輸數(shù)據(jù)。以的根元素出現(xiàn)。代理這么一個(gè)概念就更加清晰了。

WebService介紹

首先我們來(lái)談一下為什么需要學(xué)習(xí)webService這樣的一個(gè)技術(shù)吧....

問(wèn)題一

如果我們的網(wǎng)站需要提供一個(gè)天氣預(yù)報(bào)這樣一個(gè)需求的話,那我們?cè)撛趺醋觯?????/p>

天氣預(yù)報(bào)這么一個(gè)功能并不是簡(jiǎn)單的JS組件就能夠?qū)崿F(xiàn)的,它的數(shù)據(jù)是依賴數(shù)據(jù)庫(kù)分析出來(lái)的,甚至需要衛(wèi)星探測(cè)..我們個(gè)人建站是不可能搞這么一個(gè)數(shù)據(jù)庫(kù)的吧。

那么既然我們自己干不了,我們可以去找別人嗎???我們從搜索引擎搜索,可以發(fā)現(xiàn)很多提供天氣預(yù)報(bào)的網(wǎng)站,但是它返回的是一個(gè)網(wǎng)頁(yè),而我們僅僅需要的是對(duì)應(yīng)的數(shù)據(jù)!

我們可能就在想,我們能不能僅僅只要它返回的數(shù)據(jù),而并不是經(jīng)過(guò)加工處理后返回的網(wǎng)頁(yè)呢??

于是乎,webService就誕生了,webservice就是一個(gè)部署在Web服務(wù)器上的,它向外界暴露出一個(gè)能夠通過(guò)Web進(jìn)行調(diào)用的API。也就是說(shuō):當(dāng)我們想要獲取天氣預(yù)報(bào)的信息,我們可以調(diào)用別人寫好的service服務(wù),我們調(diào)用就能夠得到結(jié)果了!

問(wèn)題二

可是我們寫網(wǎng)站主流的就有好幾個(gè)平臺(tái):Java、.net、PHP等等,那么部署在Web服務(wù)器上的服務(wù)器也就是webserice怎么能夠就讓我們不同的平臺(tái)都能夠調(diào)用呢??

我們知道java、.net這樣的平臺(tái)他們語(yǔ)言的基本數(shù)據(jù)類型、復(fù)雜數(shù)據(jù)類型就可能不一樣,那么怎么能夠?qū)崿F(xiàn)調(diào)用的呢???

來(lái)引用一段話

大家在寫應(yīng)用程序查詢數(shù)據(jù)庫(kù)時(shí),并沒(méi)有考慮過(guò)為什么可以將查詢結(jié)果返回給上層的應(yīng)用程序,甚至認(rèn)為,這就是數(shù)據(jù)庫(kù)應(yīng)該做的,其實(shí)不然,這是數(shù)據(jù)庫(kù)通過(guò)TCP/IP協(xié)議與另一個(gè)應(yīng)用程序進(jìn)行交流的結(jié)果,而上層是什么樣的應(yīng)用程序,是用什么語(yǔ)言,數(shù)據(jù)庫(kù)本身并不知道,它只知道接收到了一份協(xié)議,這就是SQL92查詢標(biāo)準(zhǔn)協(xié)議。

無(wú)論是Java、.net、PHP等等的平臺(tái),只要是網(wǎng)頁(yè)開(kāi)發(fā)都是可以通過(guò)http協(xié)議來(lái)進(jìn)行通信的,并且返回的數(shù)據(jù)要是通用的話,那么我們?cè)缇蛯W(xué)過(guò)這樣的一種技術(shù)【XML】

所以webservice實(shí)際上就是http+XML

對(duì)webservice的理解

WebService,顧名思義就是基于Web的服務(wù)。它使用Web(HTTP)方式,接收和響應(yīng)外部系統(tǒng)的某種請(qǐng)求。從而實(shí)現(xiàn)遠(yuǎn)程調(diào)用.

我們可以調(diào)用互聯(lián)網(wǎng)上查詢天氣信息Web服務(wù),然后將它嵌入到我們的程序(C/S或B/S程序)當(dāng)中來(lái),當(dāng)用戶從我們的網(wǎng)點(diǎn)看到天氣信息時(shí),他會(huì)認(rèn)為我們?yōu)樗峁┝撕芏嗟男畔⒎?wù),但其實(shí)我們什么也沒(méi)有做,只是簡(jiǎn)單調(diào)用了一下服務(wù)器上的一段代碼而已。

學(xué)習(xí)WebService可以將你的服務(wù)(一段代碼)發(fā)布到互聯(lián)網(wǎng)上讓別人去調(diào)用,也可以調(diào)用別人機(jī)器上發(fā)布的WebService,就像使用自己的代碼一樣.。

回顧Socket

我們?cè)趯W(xué)習(xí)Java基礎(chǔ)網(wǎng)絡(luò)編程章節(jié)已經(jīng)知道了Scoket這么一個(gè)連接了。

Socket服務(wù)端
public class SocketSer {

    public static void main(String[] args) throws Exception {

        ServerSocket ss = new ServerSocket(6666);
        boolean flag = true;
        while (flag) {
            //接收客戶端的請(qǐng)求
            System.out.println("監(jiān)聽(tīng)客戶端的數(shù)據(jù):");
            Socket sc = ss.accept();
            InputStream is = sc.getInputStream();
            byte[] buffer = new byte[1024];
            int len = -1;
            len = is.read(buffer);
            String getData = new String(buffer, 0, len);
            System.out.println("從客戶端獲取的數(shù)據(jù):" + getData);
            //業(yè)務(wù)處理 大小寫轉(zhuǎn)化
            String outPutData = getData.toUpperCase();

            //向客戶端寫數(shù)據(jù)
            OutputStream os = sc.getOutputStream();
            os.write(outPutData.getBytes("UTF-8"));

            //釋放資源
            os.close();
            is.close();
            sc.close();
        }
        ss.close();
    }

}
Socket客服端
public class SocketClient {

    public static void main(String[] args) throws Exception {
        //獲取用戶輸入的數(shù)據(jù)
        Scanner input = new Scanner(System.in);
        System.out.println("請(qǐng)輸入數(shù)據(jù):");
        String inputData = input.nextLine();

        //開(kāi)啟一個(gè)Socket端口
        Socket sc = new Socket("127.0.0.1", 6666);
        OutputStream os = sc.getOutputStream();
        os.write(inputData.getBytes());

        //獲取服務(wù)端回傳的數(shù)據(jù)
        InputStream is = sc.getInputStream();
        byte[] buffer = new byte[1024];
        int len = -1;
        len = is.read(buffer);
        String getData = new String(buffer, 0, len);
        System.out.println("從服務(wù)端獲取的數(shù)據(jù):" + getData);
        //是否流
        is.close();
        os.close();
        sc.close();
    }

}

當(dāng)我們從客戶端輸入數(shù)據(jù)以后,那么服務(wù)端就會(huì)把數(shù)據(jù)轉(zhuǎn)成是大寫

其實(shí)HTTP協(xié)議就是基于Socket對(duì)其進(jìn)行封裝,我們也可以在IE瀏覽器中對(duì)其進(jìn)行訪問(wèn).我們一樣能夠獲取得到數(shù)據(jù)!

Scoket與HTTP簡(jiǎn)述

ISO的七層模型 : 物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層、表示層、會(huì)話層、應(yīng)用層

Socket訪問(wèn) : Socket屬于傳輸層,它是對(duì)Tcp/ip協(xié)議的實(shí)現(xiàn),包含TCP/UDP,它是所有通信協(xié)議的基礎(chǔ),Http協(xié)議需要Socket支持,以Socket作為基礎(chǔ)

Socket通信特點(diǎn):

-  開(kāi)啟端口,該通信是 長(zhǎng)連接的通信 ,**很容易被防火墻攔截,可以通過(guò)心跳機(jī)制來(lái)實(shí)現(xiàn) ,開(kāi)發(fā)難度大**
- 傳輸?shù)臄?shù)據(jù)一般是字符串 ,可讀性不強(qiáng) 
- socket端口不便于推廣
- 性能相對(duì)于其他的通信協(xié)議是最優(yōu)的

Http協(xié)議訪問(wèn) :屬于應(yīng)用層的協(xié)議,對(duì)Socket進(jìn)行了封裝

- **跨平臺(tái)** 
-  **傳數(shù)據(jù)不夠友好**
- **對(duì)第三方應(yīng)用提供的服務(wù),希望對(duì)外暴露服務(wù)接口**

問(wèn)題:

數(shù)據(jù)封裝不夠友好 :可以用xml封裝數(shù)據(jù)

希望給第三方應(yīng)用提供web方式的服務(wù) (http + xml) = web Service

webService相關(guān)術(shù)語(yǔ)

名詞1:XML. Extensible Markup Language -擴(kuò)展性標(biāo)記語(yǔ)言

XML,用于傳輸格式化的數(shù)據(jù),是Web服務(wù)的基礎(chǔ)。

namespace-命名空間。

xmlns=“http://itcast.cn” 使用默認(rèn)命名空間。

xmlns:itcast=“http://itcast.cn”使用指定名稱的命名空間。

名詞2:WSDL – WebService Description Language – Web服務(wù)描述語(yǔ)言。

通過(guò)XML形式說(shuō)明服務(wù)在什么地方-地址。

通過(guò)XML形式說(shuō)明服務(wù)提供什么樣的方法 – 如何調(diào)用。

名詞3:SOAP-Simple Object Access Protocol(簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議)

SOAP作為一個(gè)基于XML語(yǔ)言的協(xié)議用于有網(wǎng)上傳輸數(shù)據(jù)。

SOAP = 在HTTP的基礎(chǔ)上+XML數(shù)據(jù)。

SOAP是基于HTTP的。

SOAP的組成如下:

Envelope – 必須的部分。以XML的根元素出現(xiàn)。

Headers – 可選的。

Body – 必須的。在body部分,包含要執(zhí)行的服務(wù)器的方法。和發(fā)送到服務(wù)器的數(shù)據(jù)。

快速入門

首先,我們來(lái)嘗試一下調(diào)用別人寫好的webService,來(lái)體驗(yàn)一把:我們?cè)L問(wèn)http://www.webxml.com.cn/zh_cn/index.aspx

進(jìn)入到里邊

當(dāng)我們輸入一個(gè)號(hào)碼,它就能夠查詢出我們的手機(jī)位置信息:

我們現(xiàn)在要做的就是將這個(gè)服務(wù)讓我們自己寫的應(yīng)用程序中也可以調(diào)用,那怎么做呢???

http-get方式訪問(wèn)webservice

public void get(String mobileCode ,String userID ) throws Exception{
        URL url=new URL("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo?mobileCode="+mobileCode+
                "&userID="+userID);
        HttpURLConnection conn=(HttpURLConnection) url.openConnection();
        conn.setConnectTimeout(5000);
        conn.setRequestMethod("GET");
        if(conn.getResponseCode()==HttpURLConnection.HTTP_OK){ //結(jié)果碼=200
            InputStream is=conn.getInputStream();
            //內(nèi)存流 ,  
            ByteArrayOutputStream boas=new ByteArrayOutputStream();
            byte[] buffer=new byte[1024];
            int len=-1;
            while((len=is.read(buffer))!=-1){
                boas.write(buffer, 0, len);
            }
            System.out.println("GET請(qǐng)求獲取的數(shù)據(jù):"+boas.toString());
            boas.close();
            is.close();
        }
    }

Http-Client 框架POST請(qǐng)求

為什么要使用HttpClient工具:

原生態(tài)的Socket基于傳輸層,現(xiàn)在我們要訪問(wèn)的WebService是基于HTTP的屬于應(yīng)用層,所以我們的Socket通信要借助HttpClient發(fā)HTTP請(qǐng)求,這樣格式才能匹配

HttpClient使用步驟如下:

創(chuàng)建 HttpClient 的實(shí)例

創(chuàng)建某種連接方法的實(shí)例,在這里是 GetMethod。在 GetMethod 的構(gòu)造函數(shù)中傳入待連接的地址

配置要傳輸?shù)膮?shù),和消息頭信息

調(diào)用第一步中創(chuàng)建好的實(shí)例的 execute 方法來(lái)執(zhí)行第二步中創(chuàng)建好的 method 實(shí)例

通過(guò)response讀取字符串

釋放連接。無(wú)論執(zhí)行方法是否成功,都必須釋放連接

    //2.Post請(qǐng)求 :通過(guò)Http-Client 框架來(lái)模擬實(shí)現(xiàn) Http請(qǐng)求
    public void post(String mobileCode ,String userID) throws Exception{

/**HttpClient訪問(wèn)網(wǎng)絡(luò)的實(shí)現(xiàn)步驟:
         *  1. 準(zhǔn)備一個(gè)請(qǐng)求客戶端:瀏覽器 
         *  2. 準(zhǔn)備請(qǐng)求方式: GET 、POST
         *  3. 設(shè)置要傳遞的參數(shù)
         *  4.執(zhí)行請(qǐng)求
         *  5. 獲取結(jié)果
         */
        HttpClient client=new HttpClient();
        PostMethod postMethod=new PostMethod("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo");
        //3.設(shè)置請(qǐng)求參數(shù)
        postMethod.setParameter("mobileCode", mobileCode);
        postMethod.setParameter("userID", userID);
        //4.執(zhí)行請(qǐng)求 ,結(jié)果碼
        int code=client.executeMethod(postMethod);
        //5. 獲取結(jié)果
        String result=postMethod.getResponseBodyAsString();
        System.out.println("Post請(qǐng)求的結(jié)果:"+result);
    }


    //2.Post請(qǐng)求 :通過(guò)Http-Client 框架來(lái)模擬實(shí)現(xiàn) Http請(qǐng)求
    public void soap() throws Exception{

        HttpClient client=new HttpClient();
        PostMethod postMethod=new PostMethod("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx");
        //3.設(shè)置請(qǐng)求參數(shù)
          postMethod.setRequestBody(new FileInputStream("c:/soap.xml"));
          //修改請(qǐng)求的頭部
          postMethod.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        //4.執(zhí)行請(qǐng)求 ,結(jié)果碼
        int code=client.executeMethod(postMethod);
        System.out.println("結(jié)果碼:"+code);
        //5. 獲取結(jié)果
        String result=postMethod.getResponseBodyAsString();
        System.out.println("Post請(qǐng)求的結(jié)果:"+result);
    }
wsimport

上面我們使用的是GET方式或者使用Http-Client框架來(lái)調(diào)用webservice的服務(wù),其實(shí)這兩種方式也有弊端

傳遞參數(shù)麻煩【get方式都寫在請(qǐng)求地址上、post方式要一個(gè)一個(gè)封裝】

解析結(jié)果麻煩【根據(jù)返回的XML來(lái)解析字符串】

如果我們可以把整個(gè)對(duì)象傳遞進(jìn)去,返回的結(jié)果更加友好的話,就好像我們平常調(diào)用Java類一樣使用webservice就好咯!

Java也提供了類似的方法,把webservice服務(wù)搞成是Java類讓我們自己調(diào)用,既然是Java類的話,那么我們使用起來(lái)就非常方便了!

把webservice服務(wù)搞成是Java類讓我們自己調(diào)用其實(shí)就是Java幫我們生成本地代理,再通過(guò)本地代理來(lái)訪問(wèn)webservice

快速入門

wsimport是Java自帶的一個(gè)命令,我們想要使用該命令,就必須配置環(huán)境變量,并且jdk的版本最好是1.7或以上

值得注意的是:ide帶的JDK版本要和wsimport生成本地的版本一致,不然就用不了?。。?/strong>

wsimport使用:

wsimport命令后面跟著的是WSDL的url路徑 語(yǔ)法 wsimport [opations]

-          wsdl_uri:wsdl 的統(tǒng)一資源標(biāo)識(shí)符
-          d  :指定要輸出的文件的位置
-          s  :表示要解析java的源碼 ,默認(rèn)解析出的是class字節(jié)碼 
-          p  : 指定輸出的包名

首先我們先把cmd的路徑退到桌面上:

然后對(duì)WSDL文件生成本地代理

該本地代理其實(shí)就是一堆的字節(jié)碼文件

將得到的字節(jié)碼文件打包成jar,那么我們只要在項(xiàng)目中導(dǎo)入jar包,就可以調(diào)用了!

語(yǔ)法

jar cvf  test.jar【jar包的名稱】 打包目錄

本來(lái)我是想將本地代理的class文件生成jar包,然后導(dǎo)入到idea環(huán)境下,那么直接調(diào)用就行了。可是idea老是報(bào)出找不到對(duì)應(yīng)的類,找了半天也找不到,很煩呀?。。?!我考慮了以下的幾種情況

生成的class文件的JVM和idea下的JVM環(huán)境不匹配【后來(lái)切換了也不行】

idea緩存原因,把idea所有緩存去掉也不行

生成的本地代理包名cn不行【???idea就是對(duì)cn這個(gè)包名報(bào)錯(cuò),后來(lái)我改成自定義的包名也不行】

最后我還是沒(méi)有找到辦法,如果知道是什么原因的,麻煩在評(píng)論中告訴我吧....因此這次的測(cè)試import,我就不僅僅生成class字節(jié)碼文件,還生成了.java文件。我就直接使用java文件來(lái)測(cè)試了。

在zhongfucheng目錄下生成本地代理,把java源碼也帶上

于是我就把java源碼復(fù)制到我的項(xiàng)目中,用java源碼來(lái)進(jìn)行測(cè)試

解析WSDL

有的同學(xué)可能會(huì)疑問(wèn),為啥wsimport能那么厲害,將http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL這么一個(gè)url生成本地代理,其實(shí)我們看了WSDL文件就知道了。

值得注意的是,本地代理僅僅是有其方法,類,并不能解析出具體的實(shí)現(xiàn)的。具體的操作其實(shí)還是webservice去完成的。代理這么一個(gè)概念就更加清晰了。

自定義webservice服務(wù)

我們?cè)谏弦徽鹿?jié)中已經(jīng)使用wsimport生成本地代理來(lái)調(diào)用webservice的服務(wù)了,其實(shí)我們自己寫的web應(yīng)用程序也是可以發(fā)布webservice的

我們發(fā)布了webservice的話,那么其他人也是可以調(diào)用我們自己寫的webservice!

那么我們?cè)趺醋远xwebservice然后發(fā)布出去呢???

在jdk 1.6 版本以后 ,通過(guò)jax-ws 包提供對(duì)webservice的支持

該方式通過(guò)注解的方式來(lái)聲明webservice

通過(guò) jdk EndPoint.publish()發(fā)布webserive服務(wù)

快速入門

寫一個(gè)實(shí)體:

public class Phone {
    private String name;//操作系統(tǒng)名
    private String owner;//擁有者 
    private int total;//市場(chǎng)占有率
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getOwner() {
        return owner;
    }
    public void setOwner(String owner) {
        this.owner = owner;
    }
    public int getTotal() {
        return total;
    }
    public void setTotal(int total) {
        this.total = total;
    }

}

發(fā)布service,通過(guò)注解來(lái)讓W(xué)SDL文件更加可讀...

package cn.it.ws.d;

import cn.it.ws.model.Phone;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
/*
*手機(jī)的業(yè)務(wù)類,該業(yè)務(wù)類通過(guò)webservice 對(duì)外提供服務(wù)
 * 1. 聲明: @webservice
 * 2. 發(fā)布 EndPoint
 */

@WebService (serviceName="PhoneManager",//修改服務(wù)名
   targetNamespace="http://dd.ws.it.cn") //修改命名空間 ,默認(rèn)包名,取反
//聲明該業(yè)務(wù)類 對(duì)外提供webservice服務(wù)   ,默認(rèn)只是對(duì)public 修飾的方法對(duì)外以webservice形式發(fā)布
public class PhoneService {

/**@WebMethod(operationName="getMObileInfo"): 修改方法名
     * @WebResult(name="phone"):修改返回參數(shù)名
     * @WebParam(name="osName"):修改輸入?yún)?shù)名
     */

    @WebMethod(operationName="getMObileInfo")
    public @WebResult(name="phone") Phone getPhoneInfo(@WebParam(name="osName")String osName){
        Phone phone=new Phone();
        if(osName.endsWith("android")){
            phone.setName("android");phone.setOwner("google");phone.setTotal(80);
        }else if(osName.endsWith("ios")){
            phone.setName("ios");phone.setOwner("apple");phone.setTotal(15);
        }else{
            phone.setName("windows phone");phone.setOwner("microsoft");phone.setTotal(5);
        }
        return phone;
    }
    @WebMethod(exclude=true)//把該方法排除在外
    public void sayHello(String city){
        System.out.println("你好:"+city);
    }
    private void sayLuck(String city){
        System.out.println("好友:"+city);
    }
     void sayGoodBye(String city){
        System.out.println("拜拜:"+city);
    }
    protected void saySayalala(String city){
         System.out.println("再見(jiàn)!"+city);
     }
    
    public static void main(String[] args) {
        String address1="http://127.0.0.1:8888/ws/phoneService";
//        String address2="http://127.0.0.1:8888/ws/phoneManager";
/**
         * 發(fā)布webservice服務(wù)
         * 1.address:服務(wù)的地址
         * 2:implementor 服務(wù)的實(shí)現(xiàn)對(duì)象
         */

        Endpoint.publish(address1, new PhoneService());
//        Endpoint.publish(address2, new PhoneService());
        System.out.println("wsdl地址 :"+address1+"?WSDL");
    }

}

在類上添加@WebService注解,代表發(fā)布一個(gè)WebService服務(wù)

通過(guò)EndPoint(端點(diǎn)服務(wù))發(fā)布一個(gè)webService。Endpoint也是jdk提供的一個(gè)專門用于發(fā)布服務(wù)的類,它的publish方法接收兩個(gè)參數(shù),一個(gè)是本地的服務(wù)地址,二是提供服務(wù)的類。它位于javax.xml.ws.*包中。

Endpoint.publish(String address, Object implementor) 靜態(tài)方法在給定地址處針對(duì)指定的實(shí)現(xiàn)者對(duì)象創(chuàng)建并發(fā)布端點(diǎn)

給類添加上@WebService注解后,類中所有的非靜態(tài)方法都將會(huì)對(duì)外公布

如果希望某個(gè)方法不對(duì)外公開(kāi),可以在方法上添加@WebMethod(exclude=true),阻止對(duì)外公開(kāi)。

如果一個(gè)類上,被添加了@WebService注解,則必須此類至少有一個(gè)可以公開(kāi)的方法,否則將會(huì)啟動(dòng)失敗。

protected、private、final、static方法不能對(duì)外公開(kāi)

@WebService    // 添加了此注解,代表是一個(gè)WebService
public class HelloWorld {
    // 非 static final private 方法默認(rèn)會(huì)發(fā)布
    public String sayHi(String name) {
        return "hello" + name;
    }
    @WebMethod(exclude=true)
    public void exclude(){
        // 被注解排除的方法
    }
    protected void protected1(){
        //受保護(hù)的方法默認(rèn)不發(fā)布
    }
    private void private1(){
        // 私有方法默認(rèn)不發(fā)布
    }
    public static void static1(){
        // static 方法默認(rèn)不發(fā)布
    }
    public final void final1(){
        // final 方法默認(rèn)不發(fā)布
    }
}

生成的webservice能夠在瀏覽器訪問(wèn)

SOAP協(xié)議

目前WebService的協(xié)議主要有SOAP1.1和1.2。

兩者的命名空間不同。

Soap1.1的命名空間:

xmlns:soap=“http://schemas.xmlsoap.org/so... “

Soap1.2 命名空間:

xmlns:soap="http://www.w3.org/2003/05/soap-envelope“

SOAP1.1版本與SOAP1.2版本在頭信息上存在差異。

SOAP1.1存在SOAPAction的請(qǐng)求頭。

SOAP1.2沒(méi)有SOAPAction的請(qǐng)求頭。

基于SOAP1.1生成的WSDL和基于SOAP1.2生成的WSDL也不一樣。

主要看命名空間。

在CXF中兩種協(xié)議請(qǐng)求的方式也不一樣。

1.1為content-Type:text/xm;charset=UTF-8

1.2為content-Type:application/soap+xml;charset=UTF-8

SOA、UDDI概念 SOA

Soa(Service-Oriented Architecture)面向服務(wù)的架構(gòu),它是一種思想,IBM大力倡導(dǎo)是即插即用的,IBM大力提倡,希望以組裝電腦的方式來(lái)開(kāi)發(fā)應(yīng)用

組成:

面向web的服務(wù),面向web的組件 :WebService : 硬盤、cpu、內(nèi)存條

企業(yè)服務(wù)總線 (EnterPrise Service Bus :ESB)。主板

uddi

uddi (Universal Description, Discovery and Integration)統(tǒng)一描述、發(fā)現(xiàn)、集成

它是目錄服務(wù),通過(guò)該服務(wù)可以注冊(cè)和發(fā)布webservcie,以便第三方的調(diào)用者統(tǒng)一調(diào)用

用得并不太多。

實(shí)現(xiàn)接口的webservice 服務(wù)端
import javax.jws.WebService;

/**面向接口的webservice發(fā)布方式
 * 
 * 
 */
@WebService
public interface JobService {
    public String getJob();
}




import javax.jws.WebService;

@WebService(endpointInterface="cn.it.ws.e.JobService")//設(shè)置服務(wù)端點(diǎn)接口 ,指定對(duì)外提供服務(wù)的接口
public class JobServiceImpl implements JobService {

    @Override
    public String getJob() {
        return "JEE研發(fā)工程師|Android研發(fā)工程師|數(shù)據(jù)庫(kù)工程師|前端工程師|測(cè)試工程師|運(yùn)維工程師";
    }
    public void say(){
        System.out.println("早上好!");
    }
}
客戶端
import javax.xml.ws.Endpoint;

public class Test {

    public static void main(String[] args) {
        JobService jobService=new JobServiceImpl();
        String address="http://192.168.114.10:9999/ws/jobservice";
        Endpoint.publish(address, jobService);
        System.out.println("wsdl地址:"+address+"?WSDL");

    }

}
CXF框架
Apache CXF 是一個(gè)開(kāi)源的 Services 框架,CXF 幫助您來(lái)構(gòu)建和開(kāi)發(fā) Services 這些 Services 可以支持多種協(xié)議,比如:SOAP、POST/HTTP、RESTful HTTP CXF 大大簡(jiǎn)化了 Service可以天然地和 Spring 進(jìn)行無(wú)縫集成。

CXF介紹 :soa的框架

cxf 是 Celtrix (ESB框架)和 XFire(webserivice) 合并而成,并且捐給了apache

CxF的核心是org.apache.cxf.Bus(總線),類似于Spring的 ApplicationContext

CXF默認(rèn)是依賴于Spring的

Apache CXF 發(fā)行包中的jar,如果全部放到lib中,需要 JDK1.6 及以上,否則會(huì)報(bào)JAX-WS版本不一致的問(wèn)題

CXF 內(nèi)置了Jetty服務(wù)器 ,它是servlet容器,好比tomcat

CXF特點(diǎn)

與Spring、Servlet做了無(wú)縫對(duì)接,cxf框架里面集成了Servlet容器Jetty

支持注解的方式來(lái)發(fā)布webservice

能夠顯示一個(gè)webservice的服務(wù)列表

能夠添加攔截器:輸入攔截器、輸出攔截器 :

輸入日志信息攔截器、輸出日志攔截器、用戶權(quán)限認(rèn)證的攔截器

CXF開(kāi)發(fā)

要想使用CXF框架,那么就先導(dǎo)入jar包

asm-3.3.jar

commons-logging-1.1.1.jar

cxf-2.4.2.jar

jetty-continuation-7.4.5.v20110725.jar

jetty-http-7.4.5.v20110725.jar

jetty-io-7.4.5.v20110725.jar

jetty-security-7.4.5.v20110725.jar

jetty-server-7.4.5.v20110725.jar

jetty-util-7.4.5.v20110725.jar

neethi-3.0.1.jar

wsdl4j-1.6.2.jar

xmlschema-core-2.0.jar

接口

        import javax.jws.WebParam;
        import javax.jws.WebResult;
        import javax.jws.WebService;

@WebService(serviceName="languageManager")
public interface LanguageService {
    public @WebResult(name="language")String getLanguage(@WebParam(name="position")int position);

}

實(shí)現(xiàn):

package cn.it.ws.cxf.a;

import org.apache.cxf.frontend.ServerFactoryBean;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;

/**開(kāi)發(fā)語(yǔ)言排行描述服務(wù)
 * 
 * 
 * @author 李俊  2015年5月17日
 */
public class LanguageServiceImpl implements LanguageService {
    /* (non-Javadoc)
     * @see cn.it.ws.cxf.a.LanguageService#getLanguage(int)
     */
    @Override
    public String getLanguage(int position){
        String language=null;
        switch (position) {
        case 1:
            language="java"; 
            break;
        case 2:
            language="C";
            break;
        case 3:
            language="Objective-C";
            break;  
        case 4:
            language="C#";
            break;

        default:
            break;
        }
        return language;
    }
    /**通過(guò)cxf框架發(fā)布webservice
     *  1. ServerFactoryBean
     *    - 不設(shè)置注解也可以發(fā)布webservice服務(wù), 不支持注解
     *    - 不支持?jǐn)r截器的添加
     *  2. JaxWsServerFactoryBean
     *    - 支持注解
     *    - 可以添加攔截器
     *  3. webservice 訪問(wèn)流程:
     *    1. 檢測(cè)本地代理描述的wsdl是否與服務(wù)端的wsdl一致 ,俗稱為握手
     *    2. 通過(guò)soap協(xié)議實(shí)現(xiàn)通信 ,采用的是post請(qǐng)求 , 數(shù)據(jù)封裝在滿足soap規(guī)約的xml中
     *    3. 返回?cái)?shù)據(jù) 同樣采用的是soap通信,  數(shù)據(jù)封裝在滿足soap規(guī)約的xml中
     * @param args
    
    public static void main(String[] args) {
        LanguageService languageService=new LanguageServiceImpl();
        ServerFactoryBean bean=new ServerFactoryBean();
        //Endpoint :地址  , 實(shí)現(xiàn)對(duì)象
        bean.setAddress("http://192.168.114.10:9999/ws/cxf/languangeService");
        bean.setServiceClass(LanguageService.class);//對(duì)外提供webservcie的業(yè)務(wù)類或者接口
        bean.setServiceBean(languageService);//服務(wù)的實(shí)現(xiàn)bean
        bean.create();//創(chuàng)建,發(fā)布webservice
        System.out.println("wsdl地址:http://192.168.114.10:9999/ws/cxf/languangeService?WSDL");
    }
     */
    public static void main(String[] args) {
        LanguageService languageService=new LanguageServiceImpl();
        JaxWsServerFactoryBean bean=new JaxWsServerFactoryBean();
        //Endpoint :地址  , 實(shí)現(xiàn)對(duì)象
        bean.setAddress("http://192.168.114.10:9999/ws/cxf/languangeService");
        bean.setServiceClass(LanguageService.class);//對(duì)外提供webservcie的業(yè)務(wù)類或者接口
        bean.setServiceBean(languageService);//服務(wù)的實(shí)現(xiàn)bean
        //添加輸入攔截器  :輸入顯示日志信息的攔截器
        bean.getInInterceptors().add(new LoggingInInterceptor());
        //添加輸出攔截器  :輸出顯示日志信息的攔截器
        bean.getOutInterceptors().add(new LoggingOutInterceptor());
        
        bean.create();//創(chuàng)建,發(fā)布webservice
        System.out.println("wsdl地址:http://192.168.114.10:9999/ws/cxf/languangeService?WSDL");
    }

}
CXF與Spring集成

?建立一個(gè)web項(xiàng)目

?準(zhǔn)備所有jar包,將CXF_HOMElib項(xiàng)目下的所有jar包,全部都拷貝新項(xiàng)目的lib目錄下.其中里面已經(jīng)包含了Sring3.0的jar包 其中jetty 服務(wù)器的包可以不要.因?yàn)槲覀円渴鸬膖omcat服務(wù)器中了

?在web.xml中配置cxf的核心servlet,CXFServlet

?此配置文件的作用類 攔截/ws/*的所有請(qǐng)求 類似Struts2的過(guò)濾器

web.xml配置文件:



    CXF_Server
    
    
        cxf
        org.apache.cxf.transport.servlet.CXFServlet
        0
    
    
        cxf
        /ws/*
    
    
    
        org.springframework.web.context.ContextLoaderListener
    
    
        contextConfigLocation
        classpath:applicationContext.xml
    

實(shí)體:

public class Employee {
    private Integer  id;
    private String name;
    private Integer age;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }

}

接口:


package cn.it.ws.cxf.b;

import java.util.List;

import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

import cn.it.ws.cxf.bean.Employee;
@WebService(serviceName="EmployeeService")
public interface EmployeeManager {

    void add(@WebParam(name="employee")Employee employee);

    @WebResult(name="employees")List query();

}

接口實(shí)現(xiàn):

package cn.it.ws.cxf.b;

import java.util.ArrayList;
import java.util.List;

import cn.it.ws.cxf.bean.Employee;

/**員工管理的業(yè)務(wù)實(shí)現(xiàn)類
 * @author 李俊  2015年5月17日
 */
public class EmployeeManagerImpl implements EmployeeManager {
    private List employees=new ArrayList<>();
    @Override
    public void add(Employee employee){
        //添加到集合中
        employees.add(employee);
    }
    @Override
    public List query(){
        return employees;
    }

}

Spring配置信息:





    
    
    
        
            
        
        
        
            
        
        
            
        
    


IDEA下使用webservice

我們的Intellij idea是一個(gè)非常好用的java ide,當(dāng)然了,它也支持webservice開(kāi)發(fā)。非常好用...由于在網(wǎng)上見(jiàn)到的教程非常多,我就貼幾個(gè)我認(rèn)為比較好的教程:

http://www.biliyu.com/article/986.html

http://blog.csdn.net/u010323023/article/details/52926051

http://blog.csdn.net/dreamfly88/article/details/52350370

獲取天氣預(yù)報(bào)

我們現(xiàn)在webservice就基本入門了,現(xiàn)在我想要做的就是自己寫的網(wǎng)站能夠拿到天氣預(yù)報(bào)的信息,于是我去http://www.webxml.com.cn/zh_cn/index.aspx找到了天氣預(yù)報(bào)的服務(wù)

這個(gè)是天氣預(yù)報(bào)的WSDL地址:http://ws.webxml.com.cn/WebServices/WeatherWS.asmx,那么我們只要解析該WSDL服務(wù)即可

如果不想得到所有的信息,那么我們可以在服務(wù)上找到我們想要對(duì)應(yīng)的數(shù)據(jù),也就是說(shuō):

總結(jié)

應(yīng)用webservice的原因就在于我們需要一些服務(wù)、這些服務(wù)是我們自己不能手動(dòng)寫的。比如天氣預(yù)報(bào),于是就出現(xiàn)了webService技術(shù)。webService能夠讓我們可以獲取網(wǎng)上別人發(fā)布出來(lái)的服務(wù)。我們只要調(diào)用它,就可以獲取相關(guān)的數(shù)據(jù)了。

Socket其實(shí)就是對(duì)TCP/IP協(xié)議的一個(gè)封裝,而我們?cè)诰W(wǎng)上使用的是HTTP協(xié)議。WebService也是Web應(yīng)用程序。它也當(dāng)然支持HTTP協(xié)議了。不過(guò)WebService需要給不同語(yǔ)言都能夠使用,因此它使用XML來(lái)進(jìn)行傳輸。

于是,它就有自己一種協(xié)議:SOAP(簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議)。其實(shí)SOAP就是Http+XML。

我們可以使用http-get方式訪問(wèn)webservice,由于它使用的是原生Socket來(lái)進(jìn)行訪問(wèn)。會(huì)有點(diǎn)復(fù)雜。于是我們可以借助Http-Client 框架來(lái)訪問(wèn)WebService。Http-Client 框架比HTTP-GET方式會(huì)簡(jiǎn)單一點(diǎn)。但還是不夠簡(jiǎn)潔。

最后,我們可以使用Java自帶的WsImport來(lái)實(shí)現(xiàn)本地代理。這種方法會(huì)將WebService翻譯成Java類,我們使用類一樣去訪問(wèn)WebService就行了。非常好用。

我們是可以自己寫webService的。對(duì)服務(wù)類上加上注解。通過(guò)EndPoint(端點(diǎn)服務(wù))就能夠把我們webService服務(wù)類發(fā)布出去了。

為了讓W(xué)DSL文件更加讀取,可以使用注解的方式來(lái)寫好對(duì)應(yīng)的參數(shù)名稱。

也可以控制某方法是否被發(fā)布出去

SOAP其實(shí)上就是使用XML進(jìn)行傳輸?shù)腍TTP協(xié)議。

SOA:面向服務(wù)架構(gòu)。即插即用。也就是耦合非常低,用的時(shí)候加上就行了。

UDDI (Universal Description, Discovery and Integration)統(tǒng)一描述、發(fā)現(xiàn)、集成,其實(shí)就是一個(gè)webservice的目錄結(jié)構(gòu),不過(guò)我們很少把webservice發(fā)布到上面去

實(shí)現(xiàn)接口的webservice只是在類上對(duì)其的一種抽象而已,沒(méi)什么大不了的。

CXF框架可以與spring無(wú)縫連接,就不用我們自己Endpoint了。它還能記錄日志之類的。

我們還可以使用Idea下的webservice,能夠使用圖形畫面的方式獲取本地代理和生成WSDL文件。

如果文章有錯(cuò)的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章,想要獲取更多的Java資源的同學(xué),可以關(guān)注微信公眾號(hào):Java3y

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/68833.html

相關(guān)文章

  • spring boot開(kāi)發(fā)soap webservice

    摘要:本文介紹如何在中開(kāi)發(fā)接口,以及接口如何同時(shí)支持和兩種協(xié)議。該功能很簡(jiǎn)單,就是通過(guò)一個(gè)人的姓名查詢這個(gè)人的詳細(xì)信息。就是關(guān)鍵,如本次請(qǐng)求報(bào)文如下就是,對(duì)應(yīng)。測(cè)試使用進(jìn)行測(cè)試,通過(guò)地址導(dǎo)入文件進(jìn)行測(cè)試。測(cè)試這樣就實(shí)現(xiàn)了和同時(shí)提供的目的。 介紹spring boot web模塊提供了RestController實(shí)現(xiàn)restful,第一次看到這個(gè)名字的時(shí)候以為還有SoapController,...

    Ashin 評(píng)論0 收藏0
  • 移動(dòng)商城項(xiàng)目【總結(jié)】

    摘要:有必要建一個(gè)資源服務(wù)器存放靜態(tài)資源。一些用戶級(jí)別的數(shù)據(jù)輕量可以考慮存儲(chǔ)在中。存儲(chǔ)的是值,可以通過(guò)來(lái)對(duì)和對(duì)象之間的轉(zhuǎn)換如果我們的數(shù)據(jù)是在后臺(tái)傳過(guò)去或者轉(zhuǎn)換而成的,在前臺(tái)上并沒(méi)有做什么改變的話。 移動(dòng)商城項(xiàng)目總結(jié) 移動(dòng)商城項(xiàng)目是我第二個(gè)做得比較大的項(xiàng)目,該項(xiàng)目系統(tǒng)來(lái)源于傳智Java168期,十天的視頻課程(想要視頻的同學(xué)關(guān)注我的公眾號(hào)就可以直接獲取了) 通過(guò)這次的項(xiàng)目又再次開(kāi)闊了我的視野,...

    BlackHole1 評(píng)論0 收藏0
  • Java 遠(yuǎn)程通訊技術(shù)及原理分析

    摘要:對(duì)于與而言,則可以看做是消息傳遞技術(shù)的一種衍生或封裝。在生產(chǎn)者通知消費(fèi)者時(shí),傳遞的往往是消息或事件,而非生產(chǎn)者自身。通過(guò)消息路由,我們可以配置路由規(guī)則指定消息傳遞的路徑,以及指定具體的消費(fèi)者消費(fèi)對(duì)應(yīng)的生產(chǎn)者。采用和來(lái)進(jìn)行遠(yuǎn)程對(duì)象的通訊。 消息模式 歸根結(jié)底,企業(yè)應(yīng)用系統(tǒng)就是對(duì)數(shù)據(jù)的處理,而對(duì)于一個(gè)擁有多個(gè)子系統(tǒng)的企業(yè)應(yīng)用系統(tǒng)而言,它的基礎(chǔ)支撐無(wú)疑就是對(duì)消息的處理。與對(duì)象不同,消息本質(zhì)上...

    rozbo 評(píng)論0 收藏0
  • 實(shí)現(xiàn)一個(gè)spring webservice服務(wù)端三:實(shí)現(xiàn)一個(gè)有復(fù)雜返回值的spring-ws服務(wù)

    摘要:,將類或枚舉類型映射到模式類型,控制字段或?qū)傩缘男蛄谢?。表示將自?dòng)綁定類中的每個(gè)非靜態(tài)的非瞬態(tài)的由標(biāo)注字段到。,對(duì)于數(shù)組或集合即包含多個(gè)元素的成員變量,生成一個(gè)包裝該數(shù)組或集合的元素稱為包裝器。 在經(jīng)過(guò)前面兩篇文章的學(xué)習(xí),我已經(jīng)能夠熟練創(chuàng)建一個(gè)正常運(yùn)行的spring-ws的webservice服務(wù),大多數(shù)接口,都是要有返回?cái)?shù)據(jù),所以這篇文章就是學(xué)習(xí)spring-ws怎么實(shí)現(xiàn)返回?cái)?shù)據(jù) 實(shí)...

    xinhaip 評(píng)論0 收藏0
  • SpringBoot 使用CXF 集成WebService

    摘要:?jiǎn)?dòng)后我們直接輸入項(xiàng)目地址指定的服務(wù)名會(huì)看到生成的。測(cè)試在這就不寫了,大家可以使用生成客戶端,或者直接使用發(fā)送格式數(shù)據(jù)進(jìn)行請(qǐng)求。總結(jié)使用集成開(kāi)發(fā)很簡(jiǎn)單,不用在單獨(dú)的部署到外部上,這為我們熟悉開(kāi)發(fā)的同學(xué)帶了很好的體驗(yàn)。 1、寫在前面 WebService 對(duì)我來(lái)說(shuō)既熟悉又陌生,已經(jīng)將近六七年沒(méi)有看到過(guò)他了, 具體的介紹我就不多少了, 想了解的百度百科下說(shuō)的很詳細(xì)。 之所以突然研究WebS...

    miracledan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<