隨筆-46  評論-64  文章-2  trackbacks-0

          一、一些概念

          ????WebService技術現(xiàn)在幾乎無處不在,以前玩.NET的時候最開始接觸這個概念,C#語言對WebService近似原生性的支持使我們用C#可以非常迅速的開發(fā)出一個WebService,沒有任何復雜煩擾的步驟。
          ????后來沒有機會再在.Net Framework上面開發(fā),轉投了Java的懷抱,想要開發(fā)出一個WebService感覺比較,搞一堆命令生成一堆什么代碼,好不容易才能搭出來,嘗試一次之后終于還是放棄了,覺得麻煩。
          ????Java6.0出來之后對WebService也說原生支持了,所以再做畢業(yè)設計的時候想到體驗一下Java6.0的WebService,果然容易上手很多,易用。畢業(yè)設計把這個計算在內(nèi),智能設備+WebService可以作為系統(tǒng)應用的一部分。

          ???開始代碼之前先大概說說我對這幾個概念的理解

          ????WebService 是分布式應用程序組件,這么說可能太抽象,這其實以經(jīng)不是一個新的概念了,但是突然間要解釋這個名次還比較不容易。它其實是構建在已有技術基礎上的一個概念,WebService的核心是xml、soap、wsdl等,客戶可以通過web請求的方式使用WebService。或者說得更通俗點就是服務提供商把他提供的服務發(fā)布到Internet上,然后客戶可以通過Internet使用這個服務。

          ????RMI這個東西上手也不那么容易,不過這個概念可以簡單點來理解,就是不同JVM之間通訊的一個手段,這里調(diào)用的是Java代碼。不同的JVM可以在不同的機器上或者是同一臺機器上。這個純Java的分布式應用的一個典型的Solution. RMI技術和CORBA互為補充。
          ???
          ???對于CORBA我沒有詳細學習過,不過概念很容易懂,CORBA 允許應用程序和其他的應用程序通訊,而不論他們在什么地方或者由誰來設計。CORBA和語言實現(xiàn)是無關的,C++和Java實現(xiàn)的系統(tǒng)通過CORBA通信。EMA里面就有這個CORBA。

          二、協(xié)作的需求模型

          ????下面切入正題,說說WebService和RMI的協(xié)作。我們先來看這個需求的模型是怎么樣的。看下圖
          ??????????????????????????????? WebService + RMI 協(xié)作.png
          ?
          ???系統(tǒng)要求有Smart device對遠程的JVM2里的程序控制,所以我們引入了WebService,通過WebService間接調(diào)用JVM2里的東西,WebSerivce本身運行在JVM1,JVM1和JVM2可以在不同機器上,這里demo程序是在一臺機器上運行的。
          ???WebService在這里既是SmartDevice的Server端,又是RMI的Client端。RMI的Server端在JVM2的App里作為一部分服務存在。

          三、代碼分解,下面我們開始demo這個協(xié)作的代碼

          3.1 首先我們抽象一個RMI的Interface

          package ?cn.heapstack.rmi.interfaces;

          import ?java.rmi.Remote;
          import ?java.rmi.RemoteException;
          import ?java.util.Date;

          public ? interface ?IBridge? extends ?Remote
          {
          ????
          public ?Date?getDate()? throws ?RemoteException;
          ????
          ????
          public ?String?getOtherInfo()? throws ?RemoteException;
          }

          簡單的接口,一個是獲得時間的,一個是獲取隨便什么消息的接口

          3.2實現(xiàn)RMI的Server端

          package ?cn.heapstack.rmi.server;

          import ?java.rmi.RemoteException;
          import ?java.rmi.server.UnicastRemoteObject;
          import ?java.util.Date;

          import ?cn.heapstack.rmi.interfaces.IBridge;

          public ? class ?BriderImpl? extends ?UnicastRemoteObject? implements ?IBridge
          {

          ????
          protected ?BriderImpl()? throws ?RemoteException
          ????
          {
          ????????
          super ();
          ????}


          ????
          private ? static ? final ? long ?serialVersionUID? = ? - 2194578051853930272L ;

          ????
          public ?Date?getDate()? throws ?RemoteException
          ????
          {
          ????????
          return ? new ?Date( 2008 , 5 , 10 );
          ????}


          ????
          public ?String?getOtherInfo()? throws ?RemoteException
          ????
          {
          ????????
          return ? " This?is?the?message?from?the?jvm,?path?info:? " ? + ?BriderImpl. class .getResource( " / " ).getPath();
          ????}


          }

          ?

          package ?cn.heapstack.rmi.server;


          import ?java.rmi.Naming;
          import ?java.rmi.registry.LocateRegistry;

          import ?cn.heapstack.rmi.interfaces.IBridge;

          public ? class ?RmiServer?
          {

          ????
          public ? static ? void ?main(String[]?args)
          ????
          {
          ?????????
          try ???
          ??????????
          {????
          ?????????????LocateRegistry.createRegistry(
          1099 );????
          ?????????????IBridge?bridge?
          = ? new ?BriderImpl();
          ?????????????Naming.rebind(
          " bridge " ,?bridge);????
          ?????????????
          ?????????????System.out.println(
          " RMI?Server?is?ready. " );
          ??????????}
          ????
          ??????????
          catch ?(Exception?e)????
          ??????????
          {????
          ?????????????System.out.println(
          " RMI?Server?failed:? " ? + ?e);????
          ??????????}
          ????

          ????}

          }



          3.3我們可以先寫個RMI的Client測試一下
          package ?cn.heapstack.rmi.client;

          import ?java.rmi.Naming;

          import ?cn.heapstack.rmi.interfaces.IBridge;

          public ? class ?RmiClient
          {

          ????
          /**
          ?????*?
          @param ?args
          ?????
          */

          ????
          public ? static ? void ?main(String[]?args)
          ????
          {
          ????????IBridge?bridge;
          ????????
          try
          ????????
          {
          ????????????bridge?
          = ?(IBridge)?Naming.lookup( " bridge " );
          ????????
          ????????
          ????????????System.out.println(?bridge.getDate()?);
          ????????}

          ????????
          catch (Exception?e)
          ????????
          {
          ????????????e.printStackTrace();
          ????????}


          ????}


          }


          ??????由于在本機上,省略了ip什么的,如果對這段代碼不是很懂,建議看后面的參考資料
          ??????測試方法,先運行Server,再運行Client,不出以外,你能看到2008年5月10號。

          3.4我們開始實現(xiàn)我們的WebService Server端
          ??????Java6.0實現(xiàn)WebService也很簡單,我直接貼代碼了。Server端如下,如果不太懂,還是建議看后面的參考資料
          package?cn.heapstack.ws.server;

          import?java.net.MalformedURLException;
          import?java.rmi.Naming;
          import?java.rmi.NotBoundException;
          import?java.rmi.RemoteException;
          import?java.util.Date;

          import?javax.jws.WebMethod;
          import?javax.jws.WebService;
          import?javax.jws.soap.SOAPBinding;

          import?cn.heapstack.rmi.interfaces.IBridge;

          @WebService(targetNamespace?
          =?"http://www.heapstack.cn/ws/MyTimeServer")
          @SOAPBinding(style?
          =?SOAPBinding.Style.RPC)
          public?class?MyTimeServer
          {

          ????
          ????@WebMethod
          ????
          public?String?getServerTime()
          ????
          {
          ????????
          //通常的做法
          ????????
          //return?new?Date(System.currentTimeMillis()).toString();
          ????????
          ????????
          //這里我想要調(diào)用RMI,取得另一個JVM中程序調(diào)用的結果,當然這個JVM可以在兩外一臺機器上運行
          ????????
          //這里WebService的Server?其實是RMI的?Client
          ????????Date?date?=?null;
          ????????
          try
          ????????
          {
          ????????????IBridge?bridge?
          =?(IBridge)?Naming.lookup("bridge");
          ????????????date?
          =?bridge.getDate();
          ????????????
          return?date.toString();
          ????????}

          ????????
          catch(Exception?e)
          ????????
          {
          ????????????e.printStackTrace();
          ????????}

          ????????
          return?null;

          ????????
          ????}


          }

          發(fā)布WebService
          package?cn.heapstack.ws.server;

          import?javax.xml.ws.Endpoint;

          import?cn.heapstack.ws.server.MyTimeServer;
          public?class?Main
          {

          ????
          public?static?void?main(String[]?args)
          ????
          {
          ????????Endpoint.publish(
          "http://localhost:8435/MyTimeServer",?new?MyTimeServer());
          ????}


          }


          3.6實現(xiàn)WebService的客戶端
          ??????首先cd到src目錄,然后敲wsimport -keep http://localhost:8435/MyTimeServer?wsdl這個會自動生成一堆代碼,基本上可以理解為stub一類的東西
          ??????然后我們就可以直接調(diào)用啦
          package?cn.heapstack.ws.client;

          import?cn.heapstack.ws.mytimeserver.*
          ;

          public?class
          ?WSClient
          {

          ????
          /**
          ?????*?
          @param?args
          ?????
          */

          ????
          public?static?void?main(String[]?args)
          ????
          {
          ????????
          //自動生成的代碼????WebService的Stub

          ????????MyTimeServerService?ws?=?new?MyTimeServerService();
          ????????
          //自動生成的代碼????WebService的實例類

          ????????MyTimeServer?service?=?ws.getMyTimeServerPort();
          ????????
          //調(diào)用WebService,WebSerivce會調(diào)用RMI的方法獲得返回結果

          ????????String?date?=?service.getServerTime();
          ????????System.out.println(
          "WS?Client?get:"+
          ?date?);

          ????}

          }


          到此為止,這個WebService和RMI的協(xié)作完成了,代碼盡量精簡了

          參考資料:
          ??????JAVA RMI 實例-damies -JavaEye技術社區(qū),? RMI的入門資料,很容易看懂
          ??????交口稱贊?blog中 關于java 6.0?WebService的部分,也是很好的新手學習資料
          ??????
          posted on 2007-03-31 21:27 jht 閱讀(3691) 評論(3)  編輯  收藏 所屬分類: J2SE

          評論:
          # re: 使用WebService 和RMI遠程協(xié)作 2012-03-08 10:57 | try_lin
          測試rmi注冊時 報錯
          java.rmi.StubNotFoundException: Stub class not found: server.TaskRemoteImp_Stub; nested exception is:
          java.lang.ClassNotFoundException: server.TaskRemoteImp_Stub
          at sun.rmi.server.RemoteProxy.getStub(RemoteProxy.java:98)
          at sun.rmi.server.RemoteProxy.getStub(RemoteProxy.java:55)
          at sun.rmi.server.UnicastServerRef.setSkeleton(UnicastServerRef.java:179)
          at sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:142)
          at sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:129)
          at java.rmi.server.UnicastRemoteObject.exportObject(UnicastRemoteObject.java:275)
          at java.rmi.server.UnicastRemoteObject.exportObject(UnicastRemoteObject.java:178)
          at java.rmi.server.UnicastRemoteObject.<init>(UnicastRemoteObject.java:75)
          at java.rmi.server.UnicastRemoteObject.<init>(UnicastRemoteObject.java:61)
          at server.TaskRemoteImp.<init>(TaskRemoteImp.java:13)
          at rmiMain.main(rmiMain.java:16)
          Caused by: java.lang.ClassNotFoundException: server.TaskRemoteImp_Stub
          at java.net.URLClassLoader$1.run(URLClassLoader.java:199)
          at java.security.AccessController.doPrivileged(Native Method)
          at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
          at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
          at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)
          at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
          at sun.rmi.server.RemoteProxy.loadClassFromClass(RemoteProxy.java:191)
          at sun.rmi.server.RemoteProxy.getStub(RemoteProxy.java:93)
          ... 10 more
          Exception in thread "main"

          報錯 。。。。。。。。
          和你的寫法一致 jdk1.4


          怎么解決呢??  回復  更多評論
            
          # re: 使用WebService 和RMI遠程協(xié)作 2012-03-08 10:58 | try_lin
          請把解決方案發(fā)我郵箱號碼 try_lin@sina.cn
            回復  更多評論
            
          # re: 使用WebService 和RMI遠程協(xié)作 2013-12-10 15:37 | 11
          實現(xiàn)類沒有找到  回復  更多評論
            
          主站蜘蛛池模板: 启东市| 桓台县| 博兴县| 随州市| 江油市| 元阳县| 荔波县| 民丰县| 类乌齐县| 饶平县| 巨野县| 石景山区| 南靖县| 乌鲁木齐县| 大连市| 沙洋县| 丰宁| 沂源县| 乐山市| 北宁市| 信宜市| 静乐县| 横峰县| 玛曲县| 阿瓦提县| 河源市| 兴业县| 贡山| 高平市| 莱芜市| 东安县| 黄平县| 若尔盖县| 东乡| 车险| 富顺县| 通江县| 即墨市| 砀山县| 云霄县| 北辰区|