開發工具:
- Java: Netbeans6.5 (plugins: Web Services)
- dotNet: Microsoft Visual Studio 2008
dotNet 部分 (Web Service Server) :
- 透過 VS2008 在網站 (Ex: MyTest) 中建立一個名為 HelloWs.asmx 的 Web 服務.
HelloWs.cs 的程式碼如下: using System.Web.Services;
using System.Web.Services.Protocols;
/// <summary>
/// HelloWs 的摘要描述:
/// Namespace("http://tempuri.org/")將會對應至Java程式的package
/// </summary>
[WebService(Namespace = http://tempuri.org/)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class HelloWs : System.Web.Services.WebService {
public HelloHeader objHelloHeader;
public HelloWs () {
//如果使用設計的元件,請取消註解下行程式碼
//InitializeComponent();
}
/// <summary>
/// 測試用的函式:輸出此函式的參數與HelloHeader的PassKey
/// </summary>
/// <param name="name">名字</param>
/// <returns>測試用的輸出</returns>
[WebMethod]
[SoapHeader("objHelloHeader", Direction = SoapHeaderDirection.In)]
public string HelloWorld(string name) {
return string.Format("Hello {0}, your PassKey is {1}", name, objHelloHeader.PassKey);
}
}
/// <summary>
/// HelloHeader繼承自SoapHeader, 僅包含一個PassKey的屬性
/// </summary>
public class HelloHeader : SoapHeader
{
private string strPassKey;
public string PassKey
{
get { return strPassKey; }
set { strPassKey = value; }
}
}
- 在瀏覽器中輸入 http://127.0.0.1/MyTest/HelloWs.asmx , 再點選頁面中的函式名稱 (Ex: HelloWorld), 可檢視 SOAP 1.1 與 1.2 要求與回應的範例.
以下是發出 SOAP1.1 Request 的 SOAP內容:
POST /MyTest/HelloWs.asmx HTTP/1.1
Host: 127.0.0.1
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/HelloWorld" <?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:Header>
<HelloHeader xmlns="http://tempuri.org/">
<PassKey>string</PassKey>
</HelloHeader>
</soap:Header>
<soap:Body>
<HelloWorld xmlns="http://tempuri.org/">
<name>string</name>
</HelloWorld>
</soap:Body>
</soap:Envelope>
Java 部分 (Web Service Client):
- 開啟 Netbeans6.5, 並建立一個 Java Application (Ex: JavaTestApp).
- 建立一個測試用的 Java 程式 (Ex: TestHelloWorld.java).
以下有兩種呼叫 dotNet Web Service 的方式: 一種是使用 JAX-WS 2.1, 一種是使用 ksoap2.
- 使用 JAX-WS 2.1:
Step1. 在專案上建立一個 Web Service Client:
在 JavaTestApp 專案上按滑鼠右鍵 -> New -> Web Service Client… -> 輸入 WSDL 的 URL 路徑 -> 按下 Finish.
Step2. Netbeans 會幫你建立這個 Web Service Client 的相關檔案, 可在 Netbeans 中切換至 Files 模式看到以下的檔案:
- 程式的 package 與 Web Service 的 Namespace 是相關的
- 用來產生 Soap 相關物件: ObjectFactory.java
- Web Service Client 主要的程式: HelloWs.java 與 HelloWsSoap.java
- Soap Header: HelloHeader.java
- Soap 函式: HelloWorld.java
Step3. 在 Netbeans 中, 將 JAX-WS 2.1 加入至 Libraries, 不過這篇文章只需要用到以下兩個 jar:
- NetBeans 6.5\java2\modules\ext\jaxws21\jaxws-rt.jar
- NetBeans 6.5\ide10\modules\ext\jaxb\jaxb-impl.jar
Step4. 在 Netbeans 中, TestHelloWorld.java 的 main 中按滑鼠右鍵 -> Web Service Client Resources -> Call Web Service Operation… -> 按下 OK.
Step5. 在 main 中會產生呼叫 Web Service的 程式碼. 加入 Soap Header 的設定, 就能呼叫 dotNet 的 Web Service, 並傳回結果.
程式碼如下: import com.sun.xml.ws.developer.WSBindingProvider;
import org.tempuri.HelloHeader;
public class TestHelloWorld {
public static void main(String[] argd) {
try {
//呼叫Web Service的基本程式碼
org.tempuri.HelloWs service = new org.tempuri.HelloWs();
org.tempuri.HelloWsSoap port = service.getHelloWsSoap();
//設定Soap Header:HelloHeader1
HelloHeader header = new HelloHeader();
header.setPassKey("12345678");
WSBindingProvider bp = (WSBindingProvider) port;
//透過org.tempuri.ObjectFactory, 將HelloHeader轉換為JAXBElement<HelloHeader>
org.tempuri.ObjectFactory factory = new org.tempuri.ObjectFactory();
bp.setOutboundHeaders(factory.createHelloHeader(header));
// 設定呼叫HelloWorld的參數
String name = "徐武功";
// 呼叫Web Service, 並傳回結果
String result = port.helloWorld(name);
//將輸出: "Hello 徐武功, your PassKey is 12345678"
System.out.println(result);
} catch (Exception ex) {
ex.printStackTrace(System.out);
}
}
}
- 使用 ksoap2: 此做法不需要另外建立 Web Service Client.
Step1. 下載 ksoap2 和 kxml 套件:
Step2. 參考以下程式碼的說明: import java.io.StringReader;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.kxml2.io.KXmlParser;
import org.kxml2.kdom.Document;
import org.kxml2.kdom.Element;
import org.xmlpull.v1.XmlPullParser;
public class TestHelloWorld {
public static void main(String[] argd) {
try {
//產生soap header的兩種方法
//第一種利用kxml的Element, 產生header的Element[]
Element[] headers = new Element[1];
//e1是<HelloHeader xmlns="http://tempuri.org/"></HelloHeader>
Element e1 = new Element();
e1.setName("HelloHeader");
e1.setNamespace("http://tempuri.org/");
//e2是<PassKey>87654321</PassKey>
Element e2 = new Element();
e2.setName("PassKey");
e2.setNamespace("http://tempuri.org/");
//加入一個文字"87654321"
e2.addChild(Element.TEXT, "87654321");
e1.addChild(Element.ELEMENT, e2);
//將e1設定至header的Element[]
headers[0] = e1;
//第二種利用XmlPullParser, 將header的XML字串轉為kxml的Element
String strHeader = "<HelloHeader xmlns=\"http://tempuri.org/\">"
+"<PassKey>87654321</PassKey></HelloHeader>";
XmlPullParser parser = new KXmlParser();
parser.setInput(new StringReader(strHeader));
Document doc = new Document();
doc.parse(parser);
Element[] headSoap = new Element[1];
//將root element設定至headSoap的Element[]
headSoap[0] = doc.getRootElement();
String strServiceNamespace = "http://tempuri.org/";
String strServiceUrl = "http://127.0.0.1/MyTest/HelloWs.asmx?wsdl";
String strMethodName = "HelloWorld";
String strSoapAction = "http://tempuri.org/HelloWorld";
SoapObject request = new SoapObject(strServiceNamespace, strMethodName)
//設定呼叫HelloWorld的name參數
request.addProperty("name", "徐武功");
//設定呼叫SOAP1.1
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11)
envelope.dotNet = true;
//設定soap header, 可設定為headers或headSoap
envelope.headerOut = headers;
//設定soap body
envelope.setOutputSoapObject(request);
envelope.bodyOut = request;
HttpTransportSE ht = new HttpTransportSE(strServiceUrl);
//呼叫HelloWorld(name)
ht.call(strSoapAction, envelope);
//輸出"Hello 徐武功, your PassKey is 87654321"
System.out.println(envelope.getResponse());
} catch (Exception ex) {
ex.printStackTrace(System.out);
}
}
}
ksoap2 的 SOAP1.2 版我沒試成功, 因為執行時發生 xml parsing 的 exception.
如果有人試成功, 歡迎提供解決方法.
沒有留言:
張貼留言