java介面調用——webservice就是一個RPC而已

来源:http://www.cnblogs.com/intsmaze/archive/2016/11/11/6055684.html
-Advertisement-
Play Games

很多新手一聽到介面就蒙逼,不知道介面是什麼!其實介面就是RPC,通過遠程訪問別的程式提供的方法,然後獲得該方法執行的介面,而不需要在本地執行該方法。就是本地方法調用的升級版而已,我明天會上一篇如何通過socket實現rpc,以及服務的註冊和動態上下線。這裡先上一篇RPC的實現者一webservice ...


  很多新手一聽到介面就蒙逼,不知道介面是什麼!其實介面就是RPC,通過遠程訪問別的程式提供的方法,然後獲得該方法執行的介面,而不需要在本地執行該方法。就是本地方法調用的升級版而已,我明天會上一篇如何通過socket實現rpc,以及服務的註冊和動態上下線。這裡先上一篇RPC的實現者一webservice,便於後面理解源碼執行過程,框架就是在原理的基礎上提供更加便捷的使用而已,協議就是基於TCP或UDP之上,服務者和調用者之間約定消息按照什麼樣的格式發送以及解析罷了。協議沒什麼高深莫測的。

原文和作者一起討論:http://www.cnblogs.com/intsmaze/p/6055684.html

可接網站開發,java開發。

新浪微博:intsmaze劉洋洋哥

微信:intsmaze

  下麵是我多年前學習webservice時,做的筆記,今天整理一下,分享出來,為我源碼剖析RPC做準備。  

  WebService,顧名思義就是基於Web的服務。它使用Web(HTTP)方式,接收和響應外部系統的某種請求,從而實現遠程調用。我們可以調用互聯網上查詢天氣信息Web服務,然後將它嵌入到我們的程式(C/S或B/S程式)當中來,用戶可以在我們的網點看到天氣信息,他會認為我們為他提供了很多的信息服務,但其實我們只是簡單調用了一下伺服器上的一段代碼來調用別人寫好的WebService。WebService可以將你的服務(一段代碼)發佈到互聯網上讓別人去調用,也可以調用別人機器上發佈的WebService,就像使用自己的代碼一樣.

  webservice是兩個軟體系統之間的遠程調用,這裡的調用是跨語言的調用。兩個不同的應用程式之間通過xml進行數據交互的。這樣任何一種語言都可以解析xml文件中的數據。數據進行交互遵循的協議是http協議。http協議,以及我們用jdbc訪問資料庫其實底層都是依賴socket連接。比我我們經常在別的網站登錄第三方賬號也可以登錄,其實也是用的webservice,別的網站拿到賬號到第三方提供的賬號服務去驗證。

  在JDK1.6以後JAX-WS規範定義瞭如何發佈一個webService服務。
  JAX-WS是指Java Api for XML – WebService.
  用Jdk1.6.以後的版本發佈一個WebService服務.
  與Web服務相關的類,都位於javax.jws.*包中。
  主要類有:
  @WebService - 它是一個註解,將 Java 類標記為實現 Web Service,或者將 Java 介面標記為定義 Web Service 介面。
  Endpoint – 此類為端點服務類,它的方法publish用於將一個已經添加了@WebService註解對象綁定到一個地址的埠上,接收兩個參數,一個是本地的服務地址,二是提供服務的類。
  如何發佈一個web服務:
  1、在類上添加@WebService註解。
  2、通過EndPoint(端點服務)static Endpoint.publish(String address, Object implementor) 發佈一個webService。
  EndPoint發佈完成服務以後,將會啟動一個獨立的線程運行,這個啟動的線程其實就是一個servicesocket,它會接收來至其他端的socket連接。
  其他註意事項:
  1,給類添加上@WebService註解後,類中所有的非靜態方法都將會對外公佈。不支持靜態方法,final方法。
  2,如果希望某個方法(非static,非final)不對外公開,可以在方法上添加@WebMethod(exclude=true),阻止對外公開。
  3,如果一個類上,被添加了@WebService註解,則必須此類至少有一個可以公開的方法,否則將會啟動失敗。

@WebService
public class HelloService {
    public String sayHello( String intsmaze){
        System.out.println("sayHello()...");
        return  "hello " + intsmaze;
    }
    public String sayHello2(String intsmaze){
        return "hello " + intsmaze;
    }
    public static void main(String[] args) {
        Endpoint.publish("http://127.0.0.1:6789/hello ", new HelloService());
     //這個地方其實就是進行了封裝,裡面根據指定參數啟動了一個servicesocket,並且生成了一個WSDL文檔。
System.out.println(
"Server ready..."); } }

  服務發佈成功了,如何調用呢?請看說明書-WSDL:
  任何一個服務在地址欄輸入服務地址加?wsdl 如:http://127.0.0.1:6789/hello ?wsdl
  目前不是訪問webService,只是獲取一個用於描述WebService的說明文件,即:wsdl文件.wsdl- WebService Description Language,是以XML文件形式來描述WebService的”說明書”,有了說明書,我們才可以知道如何使用或是調用這個服務。

wsimport.exe是jdk自帶的,可以根據wsdl文檔生成客戶端調用代碼。
當然,無論伺服器端的WebService是用什麼語言寫的,都將在客戶端生成Java代碼.伺服器端用什麼寫的並不重要.
註意生成的這些代碼服務端並沒有,不是從服務端下載的。
wsimport.exe位於JAVA_HOME\bin目錄下.
常用參數為:
-d<目錄>  - 將生成.class文件。預設參數。
-s<目錄> - 將生成.java文件。
-p<生成的新包名> -將生成的類,放於指定的包下:-p com.intsmaze.demo
(wsdlurl) - http://server:port/service?wsdl,必須的參數。
示例:
C:/> wsimport –s . http://192.168.0.100/one?wsdl
註意:-s不能分開,-s後面有個小點,用於指定源代碼生成的目錄。點即當前目錄。(註意.前後有空格)
如果使用了-s參數則會在目錄下生成兩份代碼,一份為.class代碼。一份為.java代碼。
.class代碼,可以經過打包以後使用。java代碼可以直接Copy到我們的項目中運行。
然後只需要根據wsdl文件提供的信息調用生成類提供的方法。建議從下往上看。

  wsimport.exe是jdk自帶的,可以根據wsdl文檔生成客戶端調用java代碼,當然如果是用其他語言的類似工具,解析wsdl後將會生成對應語言的代碼,這裡只是用java為例子,註意這些代碼不是通過服務端下載的,而是通過解析wsdl生成對應java文件(就是一個本地IO)。
  wsimport.exe位於JAVA_HOME\bin目錄下.

常用參數為:
-d<目錄>  - 將生成.class文件。預設參數。
-s<目錄> - 將生成.java文件。
-p<生成的新包名> -將生成的類,放於指定的包下:-p com.intsmaze.demo
(wsdlurl) - http://server:port/service?wsdl,必須的參數。

示例:C:/> wsimport –s . http://192.168.0.100/one?wsdl
註意:-s不能分開,-s後面有個小點,用於指定源代碼生成的目錄。點即當前目錄。(註意.前後有空格)
如果使用了-s參數則會在目錄下生成兩份代碼,一份為.class代碼。一份為.java代碼。.class代碼,可以經過打包以後使用。java代碼可以直接Copy到我們的項目中運行。

生成代碼

  然後只需要根據wsdl文件提供的信息調用生成類提供的方法。建議從下往上看。

wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
xmlns:tns="http://jdkservice.intsmaze.com/" 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:ns1="http://schemas.xmlsoap.org/soap/http" 
name="HelloServiceService" 
targetNamespace="http://jdkservice.intsmaze.com/">這是服務端的包結構,一般來說通過註解修改最多,不要暴露出去!
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://jdkservice.intsmaze.com/" 
elementFormDefault
="unqualified" targetNamespace="http://jdkservice.intsmaze.com/" version="1.0"> <xs:element name="sayHello" type="tns:sayHello"/> <xs:element name="sayHelloResponse" type="tns:sayHelloResponse"/> <xs:complexType name="sayHello"> <xs:sequence> <xs:element minOccurs="0" name="arg0" type="xs:string"/> <xs:element name="arg1" type="xs:int"/> </xs:sequence> </xs:complexType> <xs:complexType name="sayHelloResponse">6,子元素說明瞭它的類型,已經是參數還是返回值 <xs:sequence> <xs:element minOccurs="0" name="return" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:schema> </wsdl:types> <wsdl:message name="sayHelloResponse">5,通過element可以知道參數類型 <wsdl:part element="tns:sayHelloResponse" name="parameters"></wsdl:part> </wsdl:message> <wsdl:message name="sayHello"> <wsdl:part element="tns:sayHello" name="parameters"></wsdl:part> </wsdl:message> <wsdl:portType name="HelloService">3,找到標簽它的子元素就是提供的方法 <wsdl:operation name="sayHello">方法名 <wsdl:input message="tns:sayHello" name="sayHello"></wsdl:input>
4,輸入參數,通過message的屬性可以知道參數類型,但是如果生成本地代碼,通過調用函數就可以知道參數類型了。 <wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse">輸出參數 </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="HelloServiceServiceSoapBinding" type="tns:HelloService">2,根據type的屬性找到對應的標簽 <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="sayHello"> <soap:operation soapAction="" style="document"/> <wsdl:input name="sayHello"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="sayHelloResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="HelloServiceService">服務的名稱,創建具體服務對象。 <wsdl:port binding="tns:HelloServiceServiceSoapBinding" 1,根據這個名稱找到對應的標簽 name="HelloServicePort">服務對象調用getHelloServicePort()獲取埠返回服務介面。 <soap:address location="http://127.0.0.1:7777/hello"/> </wsdl:port> </wsdl:service> </wsdl:definitions>

 

package com.intsmaze.jdkservice;
/**
 * 通過wsimport生成客戶端代碼調用webservice服務
 */
public class App {
    public static void main(String[] args) {
        /**
         * wsdl:<service name="HelloServiceService">
         */
        HelloServiceService hss = new HelloServiceService();
        /**
         * wsdl:<port name="HelloServicePort" binding="tns:HelloServicePortBinding">
         */
        HelloService soap = hss.getHelloServicePort();
        String str = soap.sayHello("intsmaze");//這裡我們看視乎在調用我們本地的方法,其實內部把發送數據組裝為soap協議,
然後把
數據發送到了服務端,服務端的線程接收到請求處理返回了數據。
System.out.println(str); } }

 我們使用過HttpWatch獲取的HTTP的調用過程,並獲得了HTTP的請求頭及其他請求的詳細信息。既然WebServie也是通過HTTP進行通信的,能不使用HTTPWatch來獲取它的請求過程呢?我們的代碼不僅僅是向伺服器發送的HTTP協議,更具體的說應該叫SOAP協議,它是WebService進行通信的基礎。為了獲取SOAP數據發送和接收的格式。我們有必要使用一個工具來深入的瞭解WebService.
  我們使用TCP/IP Monitor來監控攔截請求和響應具體數據的完整過程。 

以下發出HTTP請求

  響應的信息,同發送信息一樣,先必須是HTTP協議,然後再遵循SOAP協議。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • /// <summary> /// 刷新圖層列表,添加素材子元素時間控制項TimeRange /// </summary> public void RefreshListView() { for (int i = 0; i < lstCoverage.Items.Count; i++) //lstCo ...
  • asp.net實現圖片線上上傳併在線裁剪,線上上傳使用的是uploadify,線上裁剪使用的是jcrop,兩者結合併使用jquery ajax一般處理程式完美結合 ...
  • StackExchange.Redis RedisHelper.cs ...
  • 問題 想創建一個從 ASP.NET MVC controller 到 ASP.NET Web API controller 的直接鏈接,或者反向鏈接。 解決方案 可以使用 System.Web.Http.Routing.UrlHelp 的實例來創建一個指向 Controller的鏈接,來暴露ApiC ...
  • 英文文檔: 說明: 3. 可以傳入一個起始整數和一個結束整數來初始化一個range類型,生成的range類型包含起始整數(包含),和結束整數(不包含)之間的所有整數。 4. 傳入了起始整數和結束整數,還可以同時傳入一個步進值來初始化一個range類型,生成的range類型包含起始整數(包含),和結束 ...
  • ...
  • 看了網上大牛的DELPHI事件委托,實際用起來是有BUG的。代碼如下: unit faDelegate; interface uses Generics.collections, TypInfo, ObjAuto, SysUtils;type Event = class private FMetho ...
  • 1.前言: 我們知道隨著用戶數量的增長,應用軟體的規模會逐步增大,同時也使應用的服務壓力愈發大。而首當其衝的無非是資料庫操作資源... 2.技術方案: 這裡採用jndi技術實現分庫讀寫(mysql和oracle資料庫集成) 3.具體實現: a.配置tomcat的server.xml b.配置項目的w ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...