回到首頁
關於我
我的Picasa
留言板
訂閱我的文章
放大字型
原始字型
回到最上層

控制主頁

公告

感謝各位網友的造訪與回應,由於工作的關係實在沒有心力繼續維護這個BLOG。對於各位的留言,有時候真的感到心有餘而力不足,所以沒有回應的部分,還請眾網友們多多包涵。Hans在這邊感謝你們的參與~~ 2011.12.20 Hans

2008年12月15日 星期一

[筆記] JAVA 呼叫 .NET WEB SERVICE

2008 12/15 科科科~~ 這是第99篇囉~~

天氣有點冷,那是某個冬日的午後...
我悠閒的打打MSN,上上PLURK...

傑生前輩悄悄的走到我旁邊...

傑生:「翰斯阿~ 你現在有被指派什麼工作嗎?」
翰斯:「(驚!) 喔~ 沒有阿,除了偶而支援一下屠龍公司的專案,其他是沒什麼事情啦」
傑生:「那好~ 你去研究一下.NET的WEB SERVICE」
翰斯:「收到!」

於是乎這篇筆記就這樣被我拿來充版面啦~~~

話說 .NET 的 WEB SERVICE 真的是簡單到爆!M$的東西真的都很好上手~

首先呢~ 先啟動 Microsoft Visual Studio 2005 (嗯... 我目前只有2005)
File → New → Web site...

然後選 ASP.NET Web Service


開啟 Service.cs

然後開始寫程式,就完成 Web Service 的建立了!

幹!這樣就搞定了,會不會太簡單啊!

既然這麼簡單,那來試一下用JAVA呼叫.NET的WEB SERVICE好了~
想當初搞JAVA的WEB SERVICE 也是搞到快炸掉啊!

有興趣繼續往下看的請先閱讀下面這篇文章!
使用Eclipse建立Web Service

因為WEB SERVICE 主打的就是一個共通的規格,任何語言只要遵照這個規格就可以互相使用。所以我叫出.NET WEB SERVICE的WSDL,然後在Eclipse上New一個Web Service Client,接著輸入剛剛的WSDL網址,Eclipse很順利的幫我產生兩個JAVA檔。

ServiceCallbackHandler.java
ServiceStub.java

由於我寫的是一個,丟一個字串進去,會把我字串在回覆回來的 HelloWorld 程式
所以我就跟上次一樣,仿照同樣的方式寫一個程式來呼叫.NET WEB SERVIC


import org.tempuri.ServiceStub;
import org.tempuri.ServiceStub.HelloWorld;
import org.tempuri.ServiceStub.HelloWorldResponse;

public class testClient {

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

ServiceStub cs = new ServiceStub();
HelloWorld csRequest = new HelloWorld();
csRequest.setStr(".Net Web Service test");
HelloWorldResponse csResponse = cs.HelloWorld(csRequest);
System.out.println(".Net Response : " + csResponse.getHelloWorldResult());
}
}

寫好以後~~ 我RUN!

跳出一個錯誤訊息
"Exception in thread "main" org.apache.axis2.AxisFault: The input stream for an incoming message is null."

囧... 是誰說WEB SERVICE都一樣的...

在拜過Google大神後,大神給我了一個提示...

喔~ 原來再New物件的時候,要在建構子裡帶上URI的參數阿...
於是我改寫了一下程式...

2008.12.16 14:59 更新:
不加URI也是可以的,建構子會帶入預設值,所以關鍵點應該在稍後提到的那一長串程式碼。

import org.tempuri.ServiceStub;
import org.tempuri.ServiceStub.HelloWorld;
import org.tempuri.ServiceStub.HelloWorldResponse;

public class testClient {

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

String uri = "http://localhost:3514/ws/Service.asmx";
ServiceStub cs = new ServiceStub(uri);
HelloWorld csRequest = new HelloWorld();
csRequest.setStr(".Net Web Service test");
HelloWorldResponse csResponse = cs.HelloWorld(csRequest);
System.out.println(".Net Response : " + csResponse.getHelloWorldResult());
}
}


嘿嘿嘿~ 這下可搞定你了吧!我在RUN!

BB!Eclispe 又給我一個錯誤訊息!
"Exception in thread "main" org.apache.axis2.AxisFault: Software caused connection abort: recv failed"

"我操你!我操你媽的JAVA!"
人家海角阿嘉摔的是吉他
我野狼翰斯是會摔筆電的喔!

沒辦法... 只好在去請教Google大神
看了Google大神的提示後,我再度改寫程式

import org.tempuri.ServiceStub;
import org.tempuri.ServiceStub.HelloWorld;
import org.tempuri.ServiceStub.HelloWorldResponse;

public class testClient {

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

String uri = "http://localhost:3514/ws/Service.asmx";
ServiceStub cs = new ServiceStub(uri);
cs._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE);
HelloWorld csRequest = new HelloWorld();
csRequest.setStr(".Net Web Service test");
HelloWorldResponse csResponse = cs.HelloWorld(csRequest);
System.out.println(".Net Response : " + csResponse.getHelloWorldResult());
}
}

Google查來的資料說:
注意這一句!
cs._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE);

不做這個設置,一開始我怎麼都調用失敗,Axis2報告說HTTP send recv出錯(記不清楚錯誤信息了)。用tcpmon查看調用服務時的tcp傳輸,發現.net的web server根本不接受axis2的soap包。(btw,tcpmon是個不錯的工具啊。)

google了很久發現原因是,axis2在做http傳輸時採用了「chunked」模式,而.net的web server不支持。

「axis中使用的是HTTP/1.0協議,而.NET和axis2使用的是HTTP/1.1協議,後兩者的區別在於.NET未使用ns1的命名空間前綴打包SOAP請求,且axis2使用了Content-Encoding: chunked頭。 所以必須在axis2中設置一下。」


嗯... 我是有看沒有懂啦...

不過很神奇的是,加上這個就能跑了說~~

以上是這次的 "JAVA 呼叫 .NET WEB SERVICE" 的小筆記...

參考資料:
用Java調用.net的Web service ─ 趙翔鵬的Blog - Xiangpeng's Thinkpad
java使用AXIS2調用asp.net的WebService ─ heyanyang的個人空間

* * *

後來傑生又說,我們還需要在SERVER端判別連上來的CLIENT IP是多少。
由於我對.NET實在不熟,所以只好在度求助Google大神!

大神說:加上 "Context.Request.UserHostAddress" 即可!

於是我改寫 .NET的WEB SERVICE程式,讓他可以回傳我目前的IP。


using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
public Service () {

//Uncomment the following line if using designed components
//InitializeComponent();
}

[WebMethod]
public string HelloWorld(String str) {
String ip = Context.Request.UserHostAddress;
return ip;
}

}


然後就成功了... M$的東西真是超級好上手阿...

參考資料:
服務器端如何取得Client的IP地址? ─ CSDN社區

2008.12.19 10:04 補充:
JAVA WEB SERVICE AXIS2 如何取得 Client IP?

import org.apache.axis2.context.MessageContext;
import org.apache.axis2.transport.http.HTTPConstants;

public class HelloWorld {

public void getIP(){
HttpServletRequest req = (HttpServletRequest)MessageContext.getCurrentMessageContext().getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);
String clientip = req.getRemoteAddr();
System.out.println(clientip);
}

}

參考資料:Web Service 中如何得知遠端的 IP與遠端所使用的 port? ─ JavaWorld

全文 完

7 回應:

C.M. 提到...

用久了M$的東西, 買版權也會買的很上手喔~

大蛇丸 提到...

只要肯出錢
M$的東西算是很完整的solution

就像我老師說的
M$的東西起頭的時候痛一次,後續維護比較完整
Linux起頭輕鬆(free),後續維護就..(這裡指比較偏向mid-large的environment)

前提是敢砸錢,科科

Hans 提到...

各有優缺啦,沒有誰好誰壞。

然後也因為這樣,所以每種系統都有人用,也因此我們這種B2B公司,就是要幫每個客戶想辦法,把他們彼此不同的系統給串起來... Orz

匿名 提到...

使用NetBeans建立Web Service Client還滿方便的

Hans 提到...

我用eclipse 建立java的web service 的server跟client 也不難阿,只是相對於.NET .NET是真的比較簡單。

Linus 提到...

請問一下, 如果已經有一台遠端的server 架好了用 vb .net 寫的 web service, 那在開發端, 要寫 java 的程式去呼叫那個遠端 server 的 service, 需要在遠端 server 安裝 AXIS 還是在開發端? 因為我在建立 web service client 的時候發現選server的時候預設是apache tomat5.5, 可是那台遠端的server沒run tomcat啊...還有一個問題是, 我在我的開發端, 用AXIS中bin資料夾下的wsdl2java.bat針對遠端的一個 web service 的wdsl檔已經建出兩個 .java檔, packege是 ori.temuri ,
那我要如何在自己新建的java class中使用他們呢? 謝謝

匿名 提到...

您好

若.net端的webService需要soap驗證時,java端的client又要如何加入soapheader呢??