[筆記] 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 回應:
用久了M$的東西, 買版權也會買的很上手喔~
只要肯出錢
M$的東西算是很完整的solution
就像我老師說的
M$的東西起頭的時候痛一次,後續維護比較完整
Linux起頭輕鬆(free),後續維護就..(這裡指比較偏向mid-large的environment)
前提是敢砸錢,科科
各有優缺啦,沒有誰好誰壞。
然後也因為這樣,所以每種系統都有人用,也因此我們這種B2B公司,就是要幫每個客戶想辦法,把他們彼此不同的系統給串起來... Orz
使用NetBeans建立Web Service Client還滿方便的
我用eclipse 建立java的web service 的server跟client 也不難阿,只是相對於.NET .NET是真的比較簡單。
請問一下, 如果已經有一台遠端的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呢??
張貼留言