.Net/C# 与 J2EE/Java Web Service 互操作完整实例
http://www.cnblogs.com/Microshaoft/archive/2005/08/18/217213.html
.Net 與 J2EE/Java Web Service 互操作完整實例
實現支持文件分塊多點異步上傳的 J2EE/Java Web Services 及其 .Net 非 Web 客戶端應用程序異步上傳
本文參考:
實現支持文件分塊多點異步上傳的 Web Services 及其客戶端(非Web)應用程序調用相關異步執行的 Web Method
http://blog.csdn.net/playyuer/archive/2004/12/11/213069.aspx
升級到 JDK 5.0 Update 1 or 2 定制部署 WebServices - Axis 終于正常了!
http://blog.csdn.net/playyuer/archive/2005/03/01/306360.aspx
為了使程序及環境簡潔,本文均使用最簡陋的 NotePad 編寫程序或配置環境,命令行編譯程序!
不使用任何集成開發環境(IDE)!
相關源程序下載:
http://files.cnblogs.com/Microshaoft/jws.net.rar
Sever Side:
?采用 Resin/Tomcat + Axis 來部署 java Web Service。
?1.首先確認 Windows 系統中安裝(不一定要安裝,解壓到目錄即可)了如下軟件:
??J2SE(TM) Development Kit 5.0 Update 4 (JDK 5.0 Update 4):
??http://java.sun.com/j2se/1.5.0/download.jsp
??Web Application Server: Resin/Tomcat 二者有其一即可:
??Resin v2.1.16:
??http://www.caucho.com/download/resin-2.1.16.zip
??Tomcat v5.5.9:
??http://apache.justdn.org/jakarta/tomcat-5/v5.5.9/bin/jakarta-tomcat-5.5.9.zip
??下載后解壓到某目錄,如:
??D:\dotNet.J2EE\resin-2.1.16\
??或
??D:\dotNet.J2EE\jakarta-tomcat-5.5.9\
??Web Services - Axis
??http://apache.freelamp.com/ws/axis/1_2_1/axis-bin-1_2_1.zip
??下載后解壓到某目錄,如:
??D:\dotNet.J2EE\axis-1_2_1\
??然后將該目錄下的 webapps 下的 axis 子目錄,復制到:
??D:\dotNet.J2EE\resin-2.1.16\webapps\
??或
??D:\dotNet.J2EE\jakarta-tomcat-5.5.9\webapps\
??即生成如下路徑:
??D:\dotNet.J2EE\resin-2.1.16\webapps\axis\
??或
??D:\dotNet.J2EE\jakarta-tomcat-5.5.9\webapps\axis\
??至此就具備運行 Axis 的基本條件了:
??先做一下 Java Web Application Server 端口配置到 1080:
??(如果你的端口不沖突,可以跳過此步)
??Resin:
??D:\Resin\resin-2.1.16\conf\resin.conf
?
??????????<!--?the?http?port?-->??????????<http?port='1080'/>
?
??Tomcat:
??D:\dotNet.J2EE\jakarta-tomcat-5.5.9\conf
?
????????????<!--?Define?a?non-SSL?HTTP/1.1?Connector?on?port?8080?-->????????????<Connector?port="1080"?maxHttpHeaderSize="8192"
???????????????????????maxThreads="150"?minSpareThreads="25"?maxSpareThreads="75"
???????????????????????enableLookups="false"?redirectPort="8443"?acceptCount="100"
???????????????????????connectionTimeout="20000"?disableUploadTimeout="true"?/>
?
???然后,啟動 Java Web Application Server:
??Resin:
??D:\dotNet.J2EE\resin-2.1.16\bin\httpd.exe
??Tomcat:
??(啟動 Tomcat 要預先配置 JAVA_HOME 環境變量)
??D:\dotNet.J2EE\jakarta-tomcat-5.5.9\bin\start.bat
??用 IE 訪問:
??http://localhost:1080/axis/
??應該看到:
??Apache-AXIS 主頁
??點擊超鏈接:
??Validation - Validate the local installation's configuration
??see below if this does not work.
??訪問頁面:
??http://localhost:1080/axis/happyaxis.jsp
??就可以檢測當前環境是否滿足運行 Apache-AXIS。
??根據頁面提示下載到所有 zip 文件:
??http://192.18.97.238/ECom/EComTicketServlet/BEGIN8656005BAB2BAA9A4B1688FB7D4AF765/-2147483648/972910143/1/359918/359906/972910143/2ts+/westCoastFSEND/7017-jaf-1.0.2-oth-JPR/7017-jaf-1.0.2-oth-JPR:1/jaf-1_0_2-upd2.zip
??http://192.18.97.186/ECom/EComTicketServlet/BEGIN87ACAEFABC9A644DBEC89773E476BF24/-2147483648/972928407/1/540782/540770/972928407/2ts+/westCoastFSEND/javamail-1_3_2-oth-JPR/javamail-1_3_2-oth-JPR:1/javamail-1_3_2-upd.zip
??http://xml.apache.org/security/dist/java-library/xml-security-bin-1_2_1.zip
??各自解壓后得到所需所有 jar 包文件:
??activation.jar
??axis-ant.jar
??axis.jar
??commons-discovery-0.2.jar
??commons-logging-1.0.4.jar
??commons-logging-api.jar
??commons-logging.jar
??imap.jar
??jaxrpc.jar
??log4j-1.2.8.jar
??mail.jar
??mailapi.jar
??pop3.jar
??saaj.jar
??smtp.jar
??tt.txt
??wsdl4j-1.5.1.jar
??xalan.jar
??xercesImpl.jar
??xml-apis.jar
??xmlsec-1.2.1.jar
??xmlsecSamples-1.2.1.jar
??xmlsecTests-1.2.1.jar
??將這些文件全部復制到如下目錄:
??D:\dotNet.J2EE\resin-2.1.16\webapps\axis\WEB-INF\lib
??或
??D:\dotNet.J2EE\jakarta-tomcat-5.5.9\webapps\axis\WEB-INF\lib
??再次訪問:
??http://localhost:1080/axis/happyaxis.jsp
??以驗證是否完全滿足運行 Apache-AXIS 的環境,
??如無錯誤就說明已經配置好服務器了!
?2.編寫 Java Web Service 程序:
??其實實現 Web Service 的 Java 類沒啥特殊的,
??下面程序就是:
??實現支持文件分塊多點異步上傳的 Java Web Services (Server Side)
//=========================================================================
?
/**//*????Class1.jws
????Class1.java
????javac?Class1.java
????java?-cp?%axis_lib%;%classpath%;.?org.apache.axis.client.AdminClient?deploy.wsdd?-p1080
*/
import?java.io.*;
import?java.lang.*;
public?class?Class1
{
????public?static?void?main(String[]?args)?
????{
????????System.out.println("Hello?World!");
????}
????public?String?SayHelloTo(String?Who)
????{
????????return?"你好:?"?+?Who;
????}
????public?String?SayHelloToo(String?Who)
????{
????????return?"你好:?"?+?Who;
????}
????public?String?UploadFileBytes(byte[]?Bytes,String?FileName)
????????throws?Exception
????{
????????return?UploadFileChunkBytes(Bytes,?0,?FileName);
????}
????public?String?UploadFileChunkBytes(byte[]?Bytes,int?Position,String?FileName)
????????throws?Exception
????{
????????//"d:\\Server\\Upload\\"?為服務器端路徑
????????String?ServerPath?=?"d:\\Server\\Upload\\";
????????java.io.RandomAccessFile?raf?=?new?java.io.RandomAccessFile(ServerPath?+?FileName,"rws");
????????raf.skipBytes(Position);
????????raf.write(Bytes);
????????//該?Bytes?的字節要寫到?服務器端?相應文件的從?Position?開始的字節
????????raf.close();
????????raf?=?null;
????????System.gc();
????????return?FileName?+?"?文件塊:?位置["?+?Position?+?","?+?(Position?+?Bytes.length)?+?"]?大小("?+?Bytes.length?+?")?上傳成功!";
????}
????public?String?CreateBlankFile(String?FileName,int?Length)?//建議由客戶端同步調用
????????throws?Exception
????{
????????//"d:\\Server\\Upload\\"?為服務器端路徑
????????String?ServerPath?=?"d:\\Server\\Upload\\";
????????FileOutputStream?fos?=?new?FileOutputStream(ServerPath?+?FileName);
????????fos.write(new?byte[Length],?0,?Length);
????????fos.close();
????????fos?=?null;
????????System.gc()?;
????????return?FileName?+?"?("?+?Length?+?")?空白文件已經創建!";
????}
????public?byte[]?DownloadFileBytes(String?FileName)
????????throws?Exception
????{
????????File?f?=?new?File(FileName);
????????FileInputStream?fis?=?new?FileInputStream(f);
????????int?i?=?(int)?f.length();
????????byte[]?b?=?new?byte[i];
????????fis.read(b,0,i);
????????fis.close();
????????fis?=?null;
????????f?=?null;
????????System.gc()?;
????????return?b;
????}
}
?
?
//=========================================================================
??如果上面程序存為: Class1.jws 文件,直接復制到:
??D:\dotNet.J2EE\resin-2.1.16\webapps\axis\Class1.jws
??或
??D:\dotNet.J2EE\jakarta-tomcat-5.5.9\webapps\axis\Class1.jws
??即可通過 IE 直接訪問如下 URL 地址:
??http://localhost:1080/axis/Class1.jws
??這就如同 .Net Web Service .asmx 的前代碼方式
??接下來著重介紹一下定制部署 Java Web Service
??將上面程序存為: Class1.java 文件,并用如下命令行編譯:
??javac.exe Class1.java
??生成的 Class1.class 文件復制到:
??D:\dotNet.J2EE\resin-2.1.16\webapps\axis\WEB-INF\classes\Class1.class
??或
??D:\dotNet.J2EE\jakarta-tomcat-5.5.9\webapps\axis\WEB-INF\classes\Class1.class
??編寫部署文件
??deploy.wsdd (undeploy.wsdd):
?
<deployment?xmlns="http://xml.apache.org/axis/wsdd/"?xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">????<service?name="Class1Service"?provider="java:RPC">
????????<parameter?name="className"?value="Class1"/>
????????<parameter?name="allowedMethods"?value="*"/>
????</service>
</deployment>
?
??在通過如下命令行部署該 Web Service ,此時 Java Web Application Server 應已經運行:
??? java -cp %axis_lib%;%classpath%;. org.apache.axis.client.AdminClient deploy.wsdd -p1080
??如果部署成功屏幕將會輸出:
?
Processing?file?deploy.wsdd<Admin>Done?processing</Admin>
?
??如果在 Resin 上部署失敗,可在:
??D:\Resin\resin-2.1.16\conf\resin.conf
??中:
?
<war-dir?id='webapps'/>?
??后添加如下配置:
?
<!--?for?Axis?--><system-property?javax.xml.transform.TransformerFactory?=?"org.apache.xalan.processor.TransformerFactoryImpl"?/>
<system-property?javax.xml.parsers.DocumentBuilderFactory?=?"org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"?/>
<system-property?javax.xml.parsers.SAXParserFactory?=?"org.apache.xerces.jaxp.SAXParserFactoryImpl"?/>
<system-property?org.xml.sax.driver?=?"org.apache.xerces.parsers.SAXParser"?/>
?
??Tomcat 上暫沒發現上面部署失敗問題!
??部署成功后,在下面文件:
??D:\dotNet.J2EE\resin-2.1.16\webapps\axis\WEB-INF\server-config.wsdd
??或
??D:\dotNet.J2EE\jakarta-tomcat-5.5.9\webapps\axis\WEB-INF\server-config.wsdd
??中,已經被自動添加如下配置:
?
?<service?name="Class1Service"?provider="java:RPC">??<parameter?name="allowedMethods"?value="*"/>
??<parameter?name="className"?value="Class1"/>
?</service>
?
??當然也可以手工直接填寫配置 server-config.wsdd 而不使用命令行工具!
??至此如不出意外 java Web Service 已經部署完畢!
Client Side:
??http://localhost:1080/axis/services/Class1Service?wsdl
??已經可以正常訪問!
?java Client:
??還可以用解壓 axis-bin-1_2_1.zip 后:
??D:\dotNet.J2EE\axis-bin-1_2_1\axis-1_2_1\samples\client\DynamicInvoker.java
??用如下命令行編譯后:
??javac -cp %classpath%;%axis_lib%;. -Xlint:unchecked DynamicInvoker.java
??生成 DynamicInvoker.class,
??再如下命令行運行:
??java -cp %axis_lib%;%classpath%;. DynamicInvoker http://localhost:1080/axis/services/Class1Service?wsdl SayHelloTo 小平
??其中 %axis_lib% 為環境變量! 其中 %classpath% 為環境變量!
??測試如果正常則輸出:
?
Reading?WSDL?document?from?'http://localhost:1080/axis/services/Class1Service?wsdl'Preparing?Axis?dynamic?invocation
Executing?operation?SayHelloTo?with?parameters:
in0=小平
SayHelloToReturn=你好:?小平
Done!
?
?.Net Client:
??先用如下命令生成代理類的程序 C# 代碼:
??% Visual Studio .Net 2003 安裝目錄下的 %\SDK\v1.1\Bin\wsdl.exe
??具體命令行如下:
??wsdl.exe /l:CS /out:Class1ServiceProxy.cs http://localhost:1080/axis/services/Class1Service?wsdl
??然后用如下命令編譯生成程序集: Class1ServiceProxy.dll
??csc /t:library Class1ServiceProxy.cs
?
using?System;using?System.IO;
public?class?Class1
{
????static?void?Main(string[]?args)
????{
????????//Download(ServerSidepath,?ClientSidePath)
????????//Download(@"客戶端本地路徑",?@"服務器端路徑");
????????Download(@"d:\server\download\editplus.rar",?@"e:\download_editplus.rar");
????????System.Console.WriteLine("down?End");
????????System.Console.WriteLine("同步?up?file?exec?");
????????UploadFile(@"d:\Northwind.mdb");
????????System.Console.WriteLine("同步?up?file?End\n");
????????System.Console.WriteLine("異步?up?chunks?exec?");
????????UploadFileChunks(@"d:\editplus.rar",?64);
????????System.Console.ReadLine();
????}
????public?static?void?UploadFile(string?LocalFileName)
????{
????????Class1Service?xx?=?new?Class1Service();
????????FileStream?fs?=?new?FileStream(LocalFileName,?FileMode.Open);?//Client?Side?Path
????????byte[]?buffer?=?new?byte[fs.Length];
????????fs.Read(buffer,?0,?buffer.Length);
????????//調用?"同步執行"?的本地?Web?Sevices?代理類的?方法,相當于同步調用了?Web?Method?!
????????xx.UploadFileBytes(buffer,?System.IO.Path.GetFileName(LocalFileName));
?}
????//指定要上傳的本地文件的路徑,及每次上傳文件塊的大小
????public?static?void?UploadFileChunks(string?LocalFileName,int?ChunkSize)
????{
????????Class1Service?xx?=?new?Class1Service();
????????string?filename?=?System.IO.Path.GetFileName(LocalFileName);
????????FileStream?fs?=?new?FileStream(LocalFileName,?FileMode.Open);?//Client?Side?Path
????????//fs?=?File.OpenRead(LocalFileName);
????????int?r?=?(int)?fs.Length;?//用于記錄剩余還未上傳的字節數,初值是文件的大小
????????//調用?"同步執行"?的本地?Web?Sevices?代理類的?方法,相當于同步調用了?Web?Method?!
????????//預定服務器端空間
????????xx.CreateBlankFile(filename,r);
????????int?size?=?ChunkSize?*?1024;
????????int?k?=?0;?//用于記錄已經上傳的字節數
????????i++;?//用于記錄上傳的文件塊數
????????while?(r?>=?size)
????????{
????????????byte[]?buffer?=?new?byte[size];
????????????fs.Read(buffer,0,buffer.Length);
????????????//調用?"異步執行"?的本地?Web?Sevices?代理類的?方法,相當于異步調用了?Web?Method?!
????????????//該?buffer?的字節要寫到?服務器端?相應文件的從?Position?=?k?開始的字節
????????????xx.BeginUploadFileChunkBytes(buffer,k,filename,new?AsyncCallback(UploadFileChunkCallback),xx);
????????????k?+=?size;
????????????r?-=?size;
????????????i++;
????????}
????????if?(r?>?0)?//剩余的零頭
????????{
????????????byte[]?buffer?=?new?byte[r];
????????????fs.Read(buffer,0,buffer.Length);
????????????//調用?"異步執行"?的本地?Web?Sevices?代理類的?方法,相當于異步調用了?Web?Method?!
????????????//該?buffer?的字節要寫到?服務器端?相應文件的從?Position?=?k?開始的字節
????????????xx.BeginUploadFileChunkBytes(buffer,k,filename,new?AsyncCallback(UploadFileChunkCallback),xx);
????????????i++;
????????}
????????fs.Close();
????}
????private?static?int?i?=?-1;?//用于記錄上傳的文件塊數
????private?static?void?UploadFileChunkCallback(IAsyncResult?ar)
????{
????????Class1Service?x?=?(Class1Service)?ar.AsyncState;
????????Console.WriteLine(x.EndUploadFileChunkBytes(ar));
????????if?(?--i?==?0)
????????{
????????????Console.WriteLine("異步?up?all?chunks?end");
????????}
????}
????public?static?void?Download(string?ServerSideFileName,string?LocalFileName)
????{
????????Class1Service?xx?=?new?Class1Service();
????????byte[]?b?=?xx.DownloadFileBytes(ServerSideFileName);?//Server?Side?Path
????????FileStream?fs?=?new?FileStream(LocalFileName,?FileMode.Create);?//Client?Side?Path
????????fs.Write(b,0,b.Length);
????????fs.Close();
????}
}
?
??然后用如下命令編譯生成程序集: Class1ServiceClient.exe
??csc Class1ServiceClient.cs /r:Class1ServiceService.dll
??運行 Class1ServiceClient.exe 即可!
??運行結束后請檢查 D:\Server\Upload\ 目錄中是否已有文件上床!
?
總結
以上是生活随笔為你收集整理的.Net/C# 与 J2EE/Java Web Service 互操作完整实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Excel 中使用数据透视表 Pivot
- 下一篇: C#判断Textbox是否为数字