webservice 客戶端、服務端程序

webservice:主要實現跨平臺的web數據通訊java

做用:假設存在兩個業務系統,一個使用C++編寫,另一個使用Java語言編寫,若是要實現兩個不一樣的業務系統之間的數據通訊就必須進行跨平臺處理,互聯網毫無疑問就是最好的鏈接平臺。可是不一樣的業務系統之間進行通訊,就必須制定雙方都承認的規定:通訊協議,webservice正式基於soap簡單對象服務協議實現不一樣業務系統之間跨平臺通訊的.web

跨平臺通訊技術:Webservice、RMI等瀏覽器

webservice服務框架:CXF/AXIS服務器

soap請求頭:simple object access protocol:簡單對象訪問協議併發

  • SOAP 消息必須用 XML 來編碼
  • SOAP 消息必須使用 SOAP Envelope 命名空間
  • SOAP 消息必須使用 SOAP Encoding 命名空間
  • SOAP 消息不能包含 DTD 引用
  • SOAP 消息不能包含 XML 處理指令

SOAP消息組成

SOAP 消息就是一個普通的 XML 文檔,包含下列元素:框架

  1. Envelope(必需):標識XML 文檔爲一條 SOAP 消息
  2. Header(可選):包含頭部信息:通常爲消息指定某些特徵信息:例如指定自定義標籤過濾某些參數
  3. Body(必需):包含全部的調用和響應信息
  4. Fault(可選):提供有關在處理此消息所發生錯誤的信息

xmlns:soap

xml namespace 指定標籤元素名稱空間,避免衝突,而且只能放置於指定名稱空間的根元素,通常名稱空間的名稱指定爲URI,只是爲了防止命名衝突,該根標籤囊括的元素必須之前綴soap開頭,若是soap服務器接收到SOAP消息,Envelope的命名空間不是 http://schemas.xmlsoap.org/soap/envelope/,則自動拋棄該信息工具

SOAP Header

爲相互通訊的團體之間提供了一種很靈活的機制,在無需預先協定的狀況下,以分散但標準的方式擴展消息。能夠在SOAP.Header中添加條目實現這種擴展,如認證、事務管理、支付等。:Header元素是SOAP封裝元素的第一個直接子元素。Header元素的全部直接子元素稱做條目,條目的編碼規則以下:測試

  • 1個條目有完整元素名(包括名域URi和局部名),SOAP Header的直接子元素必須有名稱限制
  • SOAP encodingStyle屬性可用來指示條目所用的編碼形式
  • SOAP mustLJnderstand屬性和SOAPactor屬性可用來指示如何處理這個條目以及由誰來處理 http請求的請求頭中包含SOAPAction屬性,web端檢測到後按照SOAP消息處理

soap請求頭格式

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <ns1:sayHello xmln1:ns2="http://inter.ws.zhiwei.com/">
            <arg0>china</arg0>
        </ns1:sayHello>
    </soap:Body>
</soap:Envelope>

soap響應頭格式

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <ns1:sayHelloResponse xmlns:ns1="http://inter.ws.zhiwei.com/">
            <return>Hello china</return>
        </ns1:sayHelloResponse>
    </soap:Body>
</soap:Envelope>

SOAP和WSDL區別

  • SOAP:提供請求的格式,告訴webservice服務器,本身須要幹什麼
  • WSDL:指明webservice服務的工做類型和提供的接口,供SOAP調用

WSDL文檔組成

  1. types:指定了WebService用到的全部數據類型,上面案例用到了兩種數據類型,int和datetime編碼

  2. message:指明一個操做所用到的數據類型。spa

  3. portType:指出了這個WebService全部支持的操做,就是說有哪些方法可供調用

  4. binding:

soap12:binding元素的transport指明傳輸協議,這裏http協議

operation: 指明要暴露給外界訪問接口

use屬性指定輸入輸出的編碼方式,這裏沒有指定編碼。

  1. services:指定服務的一些信息,主要是指定服務的訪問路徑

建立Webservice服務端程序步驟

①: 建立服務接口和服務實現類 服務接口

package com.zhiwei.cxf;

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

@WebService
public interface IHelloWorld {
	public String sayHello(@WebParam(name = "name") String name);
}

服務實現類:

package com.zhiwei.cxf;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

@WebService  //標記該類爲webservice的服務類
@SOAPBinding(style = Style.RPC)
public class HelloWorld {

	//@WebParam:相似@RequestParam:將接口接受的參數暴露
	public String sayHello(@WebParam(name = "name") String name) {
		return name + " say: Hello World ";
	}
}

②:發佈webservice服務

package com.zhiwei.service;


import javax.xml.ws.Endpoint;
import com.zhiwei.cxf.*;

public class ServerDeploy {

	public static void deployService() {
		
		System.out.println("Server start .....");
		HelloWorld service = new HelloWorld();
		String address = "http://localhost:9000/helloWorld";
		
		//綁定webservice的地址和服務接口,併發布服務
		Endpoint.publish(address, service); 
	}
	
	public static void main(String[] args) throws InterruptedException {
		
		deployService();
		System.out.println("server ready .....");
		Thread.sleep(1000 * 600);
		System.out.println("server exit .....");
		System.exit(0);
	}
}

測試:瀏覽器打開http://localhost:9000/helloWorld?wsdl 可查看webservice的wsdl內容,這裏面詳細介紹了webservice服務接口的使用方法。

webservice客戶端程序

  1. 使用JAX-WS實現對webservice的訪問
  2. JDK自帶的「wsimport -keep wsdl網址」自動生成
  3. CXF框架的wsdl2java工具自動生成

方式1:JAX-WS

/**
JaxWsProxyFactoryBean:Factory for creating JAX-WS proxies 
JAX-WS:Java API for XML Web Services

功能:JAX-WS容許開發者能夠選擇RPC-oriented或者message-oriented 來實現本身的web services ,在JAX-WS中,一個遠程調用能夠轉換爲一個基於XML的協議例如SOAP,在使用JAX-WS過程當中,開發者不須要編寫任何生成和處理SOAP消息的代碼。JAX-WS的運行時實現會將這些API的調用轉換成爲對應的SOAP消息。
*/
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();

/**
* SEI:Service Endpoint Interface,服務端接口
*/
factory.setServiceClass(IHelloWorld.class); // 指定服務端提供服務的接口
factory.setAddress("http://localhost:9000/helloWorld"); // 指定服務地址

// 指定內部故障攔截器
factory.getInFaultInterceptors().add(new LoggingInInterceptor()); 

 // 指定外部故障攔截器
factory.getOutFaultInterceptors().add(new LoggingOutInterceptor());

// 建立JAX-WS服務的代理類,代理類能夠直接調用webservice中的方法
IHelloWorld service = (IHelloWorld) factory.create(); 

// 調用服務接口方法
System.out.println("[result]--->" + service.sayHello("Python"));

客戶端結果:

結果代表客戶端調用遠程的webservice服務成功。

方式2:wsimport

wsimport:自動生成的層次結構:

wsimport自動生成代碼測試:

HelloWorldService helloWorldService = new HelloWorldService();
HelloWorld helloWorld = helloWorldService.getHelloWorldPort();
System.out.println(helloWorld.sayHello("Java"));

結果:測試成功

方式3:wsdl2java

命令:wsdl2java -d d:/temp -client http://localhost:9000/helloWorld?wsdl

生成代碼結構層次:

測試代碼:

HelloWSImpService helloWSImpService=new HelloWSImpService();
		
HelloWS helloWS=helloWSImpService.getHelloWSImpPort();
String result=helloWS.sayHello("--->China!");
System.out.println(result);

結果:測試成功

Hello --->China!!

相關文章
相關標籤/搜索