隨筆-46  評(píng)論-64  文章-2  trackbacks-0

          一、一些概念

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

          ???開始代碼之前先大概說說我對(duì)這幾個(gè)概念的理解

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

          ????RMI這個(gè)東西上手也不那么容易,不過這個(gè)概念可以簡(jiǎn)單點(diǎn)來理解,就是不同JVM之間通訊的一個(gè)手段,這里調(diào)用的是Java代碼。不同的JVM可以在不同的機(jī)器上或者是同一臺(tái)機(jī)器上。這個(gè)純Java的分布式應(yīng)用的一個(gè)典型的Solution. RMI技術(shù)和CORBA互為補(bǔ)充。
          ???
          ???對(duì)于CORBA我沒有詳細(xì)學(xué)習(xí)過,不過概念很容易懂,CORBA 允許應(yīng)用程序和其他的應(yīng)用程序通訊,而不論他們?cè)谑裁吹胤交蛘哂烧l來設(shè)計(jì)。CORBA和語言實(shí)現(xiàn)是無關(guān)的,C++和Java實(shí)現(xiàn)的系統(tǒng)通過CORBA通信。EMA里面就有這個(gè)CORBA。

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

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

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

          3.1 首先我們抽象一個(gè)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;
          }

          簡(jiǎn)單的接口,一個(gè)是獲得時(shí)間的,一個(gè)是獲取隨便什么消息的接口

          3.2實(shí)現(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我們可以先寫個(gè)RMI的Client測(cè)試一下
          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();
          ????????}


          ????}


          }


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

          3.4我們開始實(shí)現(xiàn)我們的WebService Server端
          ??????Java6.0實(shí)現(xiàn)WebService也很簡(jiǎn)單,我直接貼代碼了。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,取得另一個(gè)JVM中程序調(diào)用的結(jié)果,當(dāng)然這個(gè)JVM可以在兩外一臺(tái)機(jī)器上運(yùn)行
          ????????
          //這里WebService的Server?其實(shí)是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實(shí)現(xiàn)WebService的客戶端
          ??????首先cd到src目錄,然后敲wsimport -keep http://localhost:8435/MyTimeServer?wsdl這個(gè)會(huì)自動(dòng)生成一堆代碼,基本上可以理解為stub一類的東西
          ??????然后我們就可以直接調(diào)用啦
          package?cn.heapstack.ws.client;

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

          public?class
          ?WSClient
          {

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

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

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

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

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

          ????}

          }


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

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

          評(píng)論:
          # re: 使用WebService 和RMI遠(yuǎn)程協(xié)作 2012-03-08 10:57 | try_lin
          測(cè)試rmi注冊(cè)時(shí) 報(bào)錯(cuò)
          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"

          報(bào)錯(cuò) 。。。。。。。。
          和你的寫法一致 jdk1.4


          怎么解決呢??  回復(fù)  更多評(píng)論
            
          # re: 使用WebService 和RMI遠(yuǎn)程協(xié)作 2012-03-08 10:58 | try_lin
          請(qǐng)把解決方案發(fā)我郵箱號(hào)碼 try_lin@sina.cn
            回復(fù)  更多評(píng)論
            
          # re: 使用WebService 和RMI遠(yuǎn)程協(xié)作 2013-12-10 15:37 | 11
          實(shí)現(xiàn)類沒有找到  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 苍梧县| 洛隆县| 高陵县| 耒阳市| 巨野县| 循化| 四子王旗| 灵山县| 宝坻区| 胶州市| 刚察县| 海林市| 江永县| 盐源县| 南投县| 格尔木市| 蛟河市| 洪泽县| 汤原县| 灌南县| 建平县| 屏东县| 盐池县| 石渠县| 石狮市| 象山县| 葵青区| 防城港市| 曲阜市| 金湖县| 江达县| 聊城市| 赤城县| 台山市| 丰原市| 庆安县| 仁寿县| 崇文区| 兴城市| 常熟市| 黄浦区|