Spring 2.x: Remote (RMI + HTTP)

+ andere TechDocs
+ Java, JEE, EJB
+ Spring 2.x: DI + AOP
+ Spring 2.x: DB + TX
+ Spring 2.x: MVC
+ Springframework.org
+


Dritter Teil zu Spring 2.x,
Remote Kommunikation per RMI und über HTTP:

  • RMI
  • HttpInvoker
  • Hessian
  • Burlap
  • SOAP Web Service mit XFire
    

Weitere Spring-Themen:



Inhalt

  1. Kommunikationsprotokolle
  2. Einfaches Programmierbeispiel für Remote-Kommunikation mit RMI
    Server, Client, Ausführung
  3. Einfaches Programmierbeispiel für Remote-Kommunikation über HTTP mit HttpInvoker, Hessian, Burlap und XFire-SOAP
    Server, Client, Ausführung


Kommunikationsprotokolle

Falls die Komponenten auch in einer verteilten Umgebung interagieren sollen, wird ein Netzwerkprotokoll benötigt. Spring ist mit vielen verschiedenen Protokollen verwendbar, zum Beispiel:



Einfaches Programmierbeispiel für Remote-Kommunikation mit RMI

Das folgende Beispiel erzeugt einen Server- und einen Client-Teil. Sie können beides auf dem gleichen Rechner im selben Projektverzeichnis installieren, Sie können aber auch getrennte (vernetzte) Rechner verwenden.

Teil 1: Server

  1. Führen Sie die unter Installation genannten Schritte durch, aber diesmal für das Projektverzeichnis 'SpringRemoteRmi' und das Package-Verzeichnis 'src/meinremotepckg'.
    Ihr Projektverzeichnisstruktur sollte jetzt in etwa folgendermaßen aussehen:

    [\MeinWorkspace]
      '- [SpringRemoteRmi]
           |- [bin]
           |- [lib]
           |    |- commons-logging.jar
           |    '- spring.jar
           '- [src]
                '- [meinremotepckg]
                     '- [server]
    
  2. Installieren Sie zusätzlich Ant wie zum Beispiel hier beschrieben.
  3. Erzeugen Sie im Package-Verzeichnis 'src/meinremotepckg' folgende Interface-Datei 'MeinRemoteDienstIf.java':

    package meinremotepckg;
    
    public interface MeinRemoteDienstIf
    {
      public String getMyString();
      public void setMyString( String myString );
    }
    
  4. Erzeugen Sie im Package-Verzeichnis 'src/meinremotepckg.server' folgende Implementierungsdatei 'MeinRemoteDienstImpl.java':

    package meinremotepckg.server;
    
    public class MeinRemoteDienstImpl implements meinremotepckg.MeinRemoteDienstIf
    {
      private String myString;
      public String getMyString() { return myString; }
      public void setMyString( String myString ) { this.myString = myString; }
    }
    
  5. Erzeugen Sie im Package-Verzeichnis 'src/meinremotepckg.server' folgende Java-Datei 'MainSrvr.java':

    package meinremotepckg.server;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import meinremotepckg.MeinRemoteDienstIf;
    
    public class MainSrvr
    {
      public static void main( String[] args ) throws InterruptedException
      {
        ApplicationContext appContext =
          new ClassPathXmlApplicationContext( "meinremotepckg/server/rmi-server.xml" );
        MeinRemoteDienstIf dienst =
          (MeinRemoteDienstIf) appContext.getBean( "idMeinRemoteDienst" );
        for( int i=0; i<35; i++ ) {
          System.out.println( "Server, " + i + ": " + dienst.getMyString() );
          Thread.sleep( 1000 );
          if( 0 == i % 9 )  dienst.setMyString( "Server " + i );
        }
        System.exit( 0 );
      }
    }
    
  6. Erzeugen Sie im Package-Verzeichnis 'src/meinremotepckg.server' folgende Spring-Konfigurations-XML-Datei 'rmi-server.xml':

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
              "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
      <bean id="idMeinRemoteDienst"
            class="meinremotepckg.server.MeinRemoteDienstImpl">
      </bean>
      <bean id="idMeinRemoteDienstRMI"
            class="org.springframework.remoting.rmi.RmiServiceExporter">
        <property name="serviceName"      value="MeinRemoteDienstName" />
        <property name="service"          ref="idMeinRemoteDienst" />
        <property name="serviceInterface" value="meinremotepckg.MeinRemoteDienstIf" />
      </bean>
    </beans>
    
  7. Ihr Server-Projektverzeichnis sollte jetzt in etwa folgendermaßen aussehen:

    [\MeinWorkspace]
      '- [SpringRemoteRmi]
           |- [bin]
           |- [lib]
           |    |- commons-logging.jar
           |    '- spring.jar
           '- [src]
                '- [meinremotepckg]
                     |- [server]
                     |    |- MainSrvr.java
                     |    |- MeinRemoteDienstImpl.java
                     |    '- rmi-server.xml
                     '- MeinRemoteDienstIf.java
    

Teil 2: Client

  1. Falls der Client auf einem anderen Rechner als der Server laufen soll: Richten Sie die die oben aufgeführte Projektverzeichnisstruktur ein.
    In jedem Fall müssen Sie das Package-Unterverzeichnis 'src/meinremotepckg.client' erzeugen:
    [\MeinWorkspace]
      '- [SpringRemoteRmi]
           |- [bin]
           |- [lib]
           |    |- commons-logging.jar
           |    '- spring.jar
           '- [src]
                '- [meinremotepckg]
                     '- [client]
    
  2. Falls Ihr Client-Projektverzeichnis ein anderes als das Server-Projektverzeichnis ist:
    Erzeugen Sie wieder im Package-Verzeichnis 'src/meinremotepckg' die Interface-Datei 'MeinRemoteDienstIf.java':

    package meinremotepckg;
    
    public interface MeinRemoteDienstIf
    {
      public String getMyString();
      public void setMyString( String myString );
    }
    
  3. Erzeugen Sie im Package-Verzeichnis 'src/meinremotepckg.client' folgende Java-Datei 'MainRmiClnt.java':

    package meinremotepckg.client;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import meinremotepckg.MeinRemoteDienstIf;
    
    public class MainRmiClnt
    {
      public static void main( String[] args ) throws InterruptedException
      {
        ApplicationContext appContext =
          new ClassPathXmlApplicationContext( "meinremotepckg/client/rmi-client.xml" );
        MeinRemoteDienstIf dienst =
          (MeinRemoteDienstIf) appContext.getBean( "idMeinRemoteDienst" );
        for( int i=0; i<25; i++ ) {
          System.out.println( "Client, " + i + ": " + dienst.getMyString() );
          Thread.sleep( 1000 );
          if( 0 == i % 7 )  dienst.setMyString( "Client " + i );
        }
      }
    }
    
  4. Erzeugen Sie im Package-Verzeichnis 'src/meinremotepckg.client' folgende Properties-Datei 'rmi-client.properties' und tragen Sie darin die korrekte IP-Adresse Ihres Servers ein (wenn Client und Server auf dem gleichen Rechner laufen, können Sie auch 'server.ip=localhost' setzen):

    server.ip=192.168.0.25
    
  5. Erzeugen Sie im Package-Verzeichnis 'src/meinremotepckg.client' folgende Spring-Konfigurations-XML-Datei 'rmi-client.xml':

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
      <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="meinremotepckg/client/rmi-client.properties" />
      </bean>
      <bean id="idMeinRemoteDienst"
            class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
        <property name="serviceUrl" value="rmi://${server.ip}:1099/MeinRemoteDienstName" />
        <property name="serviceInterface" value="meinremotepckg.MeinRemoteDienstIf" />
      </bean>
    </beans>
    
  6. Ihr Client-Projektverzeichnis sollte jetzt in etwa folgendermaßen aussehen:

    [\MeinWorkspace]
      '- [SpringRemoteRmi]
           |- [bin]
           |- [lib]
           |    |- commons-logging.jar
           |    '- spring.jar
           '- [src]
                '- [meinremotepckg]
                     |- [client]
                     |    |- MainRmiClnt.java
                     |    |- rmi-client.properties
                     |    '- rmi-client.xml
                     '- MeinRemoteDienstIf.java
    

Teil 3: Ausführung

  1. Öffnen Sie ein Kommandozeilenfenster für den Server, verzweigen Sie in das Projektverzeichnis 'SpringRemoteRmi' und führen Sie folgende Kommandos aus (warten Sie mit dem letzten Kommando, bis der Client-Teil fertig compiliert ist):

    cd \MeinWorkspace\SpringRemoteRmi

    set CLASSPATH=src;bin;lib/commons-logging.jar;lib/spring.jar

    javac -d bin src/meinremotepckg/server/*.java

    java meinremotepckg.server.MainSrvr

  2. Öffnen Sie ein zweites Kommandozeilenfenster für den Client, verzweigen Sie in das Projektverzeichnis 'SpringRemoteRmi' und führen Sie folgende Kommandos aus (das letzte Kommando dürfen Sie erst ausführen, wenn der Server fertig gestartet ist):

    cd \MeinWorkspace\SpringRemoteRmi

    set CLASSPATH=src;bin;lib/commons-logging.jar;lib/spring.jar

    javac -d bin src/meinremotepckg/client/*.java

    java meinremotepckg.client.MainRmiClnt

  3. Wenn Sie den Server und den Client möglichst kurz hintereinander starten, erhalten Sie ungefähr folgendes Ergebnis:

     0: null
     1: Client 0
     2: Client 0
    ...
     8: Client 7
     9: Client 7
    10: Server 9
    11: Server 9
    ...
    15: Client 14
    16: Client 14
    ...
    
  4. Bemerkungen:



Einfaches Programmierbeispiel für Remote-Kommunikation über HTTP mit HttpInvoker, Hessian, Burlap und XFire-SOAP

Das folgende Beispiel mag etwas unsinnig erscheinen, da es gleichzeitig mehrere Protokolle zur Kommunikation zwischen dem Server und dem Client verwendet. Der Sinn liegt darin, dass so demonstriert werden kann, wie einfach es ist, die Kommunikation auf andere Protokolle umzukonfigurieren, ohne dass eine Änderung an den Diensteklassen und -methoden notwendig ist. Dies kann zum Beispiel für Tests ausgenutzt werden, oder während der Entwicklung wird ein trace- und lesbares XML-Protokoll zum einfacheren Debugging verwendet und in der Produktion wird auf ein schnelleres binäres Protokoll umkonfiguriert.

Wahrscheinlich wird man selten mehrere Protokolle gleichzeitig konfigurieren, aber im folgenden Beispiel bietet dies die Möglichkeit, einen Performancevergleich anzustellen.

Das folgende Beispiel baut auf dem vorherigen auf, da es außer den HTTP-Protokollen auch RMI einbezieht.

Das Beispiel erzeugt einen Server- und einen Client-Teil. Sie können beides auf dem gleichen Rechner installieren, Sie können aber auch getrennte (vernetzte) Rechner verwenden.

Teil 1: Tomcat, Verzeichnisstruktur und .jar-Libraries

  1. Dieses Beispiel ist getestet mit den Versionen 'spring-framework-2.0-m4-with-dependencies.zip', 'xfire-distribution-1.1.zip' und 'jakarta-tomcat-5.5.9.zip'. Für andere Versionen sind eventuell Anpassungen erforderlich.
  2. Führen Sie alle im vorherigen Beispiel oben unter Einfaches Programmierbeispiel für Remote-Kommunikation mit RMI beschriebenen Schritte durch.
  3. Installieren Sie (auf dem Server) Tomcat zum Beispiel nach 'D:\Tools\Tomcat', so wie beschrieben unter jsp-install.htm#InstallationUnterWindows.
    Für eine Entwicklungsumgebung sollten Sie vorzugsweise nicht von der Tomcat-.exe-Datei sondern besser von der Tomcat-.zip-Datei installieren.
  4. Achten Sie auf korrekt gesetzte Umgebungsvariablen (Environment-Variablen) (passen Sie die Pfadangaben an Ihre Java-SDK- und '<tomcat-root>'-Verzeichnisse an):
    Benutzervariablen:
    JAVA_HOMEC:\Program Files\Java\jdk1.6
    CATALINA_HOMED:\Tools\Tomcat
  5. Legen Sie die in eckigen Klammern ([ ]) aufgeführten Verzeichnisse für folgende Projektverzeichnisstruktur an:

    [\MeinWorkspace]
      |- [SpringRemoteHttp-Clnt]
      |    |- [bin]
      |    |- [lib]
      |    |    |- activation-1.1.jar
      |    |    |- [burlap-2.1.12.jar]
      |    |    |- commons-codec-1.3.jar
      |    |    |- commons-httpclient-3.0.jar
      |    |    |- commons-logging.jar
      |    |    |- hessian-2.1.12.jar
      |    |    |- jdom-1.0.jar
      |    |    |- servlet-api-2.3.jar
      |    |    |- spring.jar
      |    |    |- stax-api-1.0.1.jar
      |    |    |- wsdl4j-1.5.2.jar
      |    |    |- wstx-asl-2.9.3.jar
      |    |    |- xfire-all-1.1.jar
      |    |    '- [XmlSchema-1.1.jar]
      |    |- [src]
      |    |    '- [meinremotepckg]
      |    |         |- [client]
      |    |         |    |- MainRemoteClnt.java
      |    |         |    |- MeinLocalDienstImpl.java
      |    |         |    |- remote-client.properties
      |    |         |    '- remote-client.xml
      |    |         '- MeinRemoteDienstIf.java
      |    '- build.xml
      '- [SpringRemoteHttp-Srvr]
           |- [src]
           |    '- [meinremotepckg]
           |         |- [server]
           |         |    '- MeinRemoteDienstImpl.java
           |         '- MeinRemoteDienstIf.java
           |- [WEB-INF]
           |    |- [classes]
           |    |- [lib]
           |    |    |- activation-1.1.jar
           |    |    |- [burlap-2.1.12.jar]
           |    |    |- hessian-2.1.12.jar
           |    |    |- jdom-1.0.jar
           |    |    |- spring.jar
           |    |    |- stax-api-1.0.1.jar
           |    |    |- wsdl4j-1.5.2.jar
           |    |    |- wstx-asl-2.9.3.jar
           |    |    '- xfire-all-1.1.jar
           |    |- applicationContext.xml
           |    |- remote-servlet.xml
           |    '- web.xml
           '- build.xml
    

    Sie können die komplette Verzeichnisstruktur wie dargestellt auf einem Rechner installieren. Alternativ können Sie die Verzeichnisstruktur auch aufteilen in den 'SpringRemoteHttp-Clnt'- und den 'SpringRemoteHttp-Srvr'-Zweig und diese auf getrennten Rechnern (für den Client und den Server) installieren.

  6. Downloaden Sie das Spring-Framework und die XFire-Distribution und kopieren Sie daraus in die beiden 'lib'-Verzeichnisse die benötigten .jar-Libraries:

Teil 2: Server

  1. Erzeugen Sie im Projektverzeichnis 'SpringRemoteHttp-Srvr' folgende Ant-Datei 'build.xml':

    <project name="MeinWebAppProjekt" default="Usage">
      <!-- <property file="build.properties" /> -->
      <!-- <property name="appserver.home" value="${CATALINA_HOME}" /> -->
      <property name="app.name"    value="MeineWebApp" />
      <property name="dist.dir"    value="dist" />
      <property name="jsp.dir"     value="jsp" />
      <property name="src.dir"     value="src" />
      <property name="WEB-INF.dir" value="WEB-INF" />
      <path id="compile.classpath">
        <fileset dir="${appserver.home}/common/lib" includes="servlet*.jar" />
        <fileset dir="${WEB-INF.dir}/lib" />
        <pathelement path="${WEB-INF.dir}/classes" />
      </path>
      <target name="Usage">
        <echo message="Commandline" />
        <echo message="  ant -Dappserver.home=%CATALINA_HOME% target" />
        <echo message="Availiable Targets" />
        <echo message="  clean     : Delete ${WEB-INF.dir}/classes" />
        <echo message="  compile   : Compile from ${src.dir} to ${WEB-INF.dir}/classes" />
        <echo message="  create-war: Create ${dist.dir}/${app.name}.war" />
        <echo message="  deploy-war: Copy ${app.name}.war to ${appserver.home}/webapps" />
      </target>
      <target name="clean"
              description="Delete ${WEB-INF.dir}/classes">
        <delete dir="${WEB-INF.dir}/classes" />
        <delete dir="${dist.dir}" />
      </target>
      <target name="compile"
              description="Compile from ${src.dir} to ${WEB-INF.dir}/classes">
        <mkdir dir="${WEB-INF.dir}/lib" />
        <mkdir dir="${WEB-INF.dir}/classes" />
        <javac srcdir="${src.dir}" destdir="${WEB-INF.dir}/classes">
          <classpath refid="compile.classpath" />
        </javac>
      </target>
      <target name="create-war" depends="compile"
              description="Create ${dist.dir}/${app.name}.war">
        <mkdir dir="${dist.dir}" />
        <mkdir dir="${jsp.dir}" />
        <war destfile="${dist.dir}/${app.name}.war" webxml="${WEB-INF.dir}/web.xml">
          <classes dir="${WEB-INF.dir}/classes" />
          <fileset dir="." includes="${WEB-INF.dir}/*.*, ${WEB-INF.dir}/lib/*.*"
                           excludes="${WEB-INF.dir}/web.xml, ${WEB-INF.dir}/lib/servlet*.jar" />
          <fileset dir="${jsp.dir}">
            <include name="**/*.*" />
          </fileset>
        </war>
      </target>
      <target name="deploy-war" depends="create-war"
              description="Copy ${app.name}.war to ${appserver.home}/webapps">
        <copy todir="${appserver.home}/webapps" preservelastmodified="true">
          <fileset dir="${dist.dir}" includes="${app.name}.war" />
        </copy>
      </target>
    </project>
    
  2. Erzeugen Sie im 'WEB-INF'-Verzeichnis folgende XML-Konfigurationsdatei 'applicationContext.xml':

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
      <bean id="idMeinRemoteDienst" class="meinremotepckg.server.MeinRemoteDienstImpl">
        <property name="myString" value="meinStartText"/>
      </bean>
    </beans>
    
  3. Erzeugen Sie im 'WEB-INF'-Verzeichnis folgende XML-Konfigurationsdatei 'remote-servlet.xml':

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
      <bean name="/MeinRemoteDienstHttpInvoker"
            class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="serviceInterface" value="meinremotepckg.MeinRemoteDienstIf" />
        <property name="service" ref="idMeinRemoteDienst" />
      </bean>
      <bean name="/MeinRemoteDienstHessian"
            class="org.springframework.remoting.caucho.HessianServiceExporter">
        <property name="serviceInterface" value="meinremotepckg.MeinRemoteDienstIf" />
        <property name="service" ref="idMeinRemoteDienst" />
      </bean>
      <bean name="/MeinRemoteDienstBurlap"
            class="org.springframework.remoting.caucho.BurlapServiceExporter">
        <property name="serviceInterface" value="meinremotepckg.MeinRemoteDienstIf" />
        <property name="service" ref="idMeinRemoteDienst" />
      </bean>
      <bean name="/MeinRemoteDienstSoap"
            class="org.codehaus.xfire.spring.remoting.XFireExporter">
        <property name="serviceInterface" value="meinremotepckg.MeinRemoteDienstIf" />
        <property name="serviceBean" ref="idMeinRemoteDienst" />
        <property name="serviceFactory" ref="xfire.serviceFactory" />
        <property name="xfire" ref="xfire" />
      </bean>
    </beans>
    
  4. Erzeugen Sie im 'WEB-INF'-Verzeichnis folgende XML-Konfigurationsdatei 'web.xml':

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app PUBLIC
      "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
      "http://java.sun.com/dtd/web-app_2_3.dtd">
    <web-app>
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
          /WEB-INF/applicationContext.xml classpath:org/codehaus/xfire/spring/xfire.xml
        </param-value>
      </context-param>
      <servlet>
        <servlet-name>context</servlet-name>
        <servlet-class>
          org.springframework.web.context.ContextLoaderServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet>
        <servlet-name>remote</servlet-name>
        <servlet-class>
          org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>2</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>remote</servlet-name>
        <url-pattern>/*</url-pattern>
      </servlet-mapping>
    </web-app>
    
  5. Erzeugen Sie im Package-Verzeichnis 'src/meinremotepckg' folgende Interface-Datei 'MeinRemoteDienstIf.java':

    package meinremotepckg;
    
    public interface MeinRemoteDienstIf
    {
      public String getMyString();
      public void setMyString( String myString );
    }
    
  6. Erzeugen Sie im Package-Verzeichnis 'src/meinremotepckg.server' folgende Implementierungsdatei 'MeinRemoteDienstImpl.java':

    package meinremotepckg.server;
    
    public class MeinRemoteDienstImpl implements meinremotepckg.MeinRemoteDienstIf
    {
      private String myString;
      public String getMyString() { return myString; }
      public void setMyString( String myString ) { this.myString = myString; }
    }
    

Teil 3: Client

  1. Erzeugen Sie im Projektverzeichnis 'SpringRemoteHttp-Clnt' folgende Ant-Datei 'build.xml':

    <project name="MeineSpringWebApp-Clnt" default="run">
      <property name="myAppClass" value="meinremotepckg.client.MainRemoteClnt" />
      <property name="mySrcDir"   value="${basedir}/src" />
      <property name="myDestDir"  value="${basedir}/bin" />
      <property name="myLibDir"   value="${basedir}/lib" />
      <target name="compile">
        <javac srcdir="${mySrcDir}" destdir="${myDestDir}" debug="on">
          <classpath>
            <fileset dir="${myLibDir}">
              <include name="*.jar" />
            </fileset>
          </classpath>
        </javac>
      </target>
      <target name="copy-resources">
        <copy todir="${myDestDir}">
          <fileset dir="${mySrcDir}">
            <exclude name="**/*.java" />
          </fileset>
        </copy>
      </target>
      <target name="run" depends="compile,copy-resources">
        <java fork="true" classname="${myAppClass}">
          <classpath>
            <fileset dir="${myLibDir}">
              <include name="*.jar" />
            </fileset>
            <pathelement path="${myDestDir}" />
          </classpath>
          <arg line="${args}" />
        </java>
      </target>
    </project>
    
  2. Erzeugen Sie das Package-Verzeichnis 'src/meinremotepckg' und darin folgende Interface-Datei 'MeinRemoteDienstIf.java':

    package meinremotepckg;
    
    public interface MeinRemoteDienstIf
    {
      public String getMyString();
      public void setMyString( String myString );
    }
    
  3. Erzeugen Sie das Package-Verzeichnis 'src/meinremotepckg.client' und darin folgende Haupt-Java-Datei 'MainRemoteClnt.java':

    package meinremotepckg.client;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import meinremotepckg.MeinRemoteDienstIf;
    
    public class MainRemoteClnt
    {
      public static void main( String[] args ) throws InterruptedException
      {
        ApplicationContext appContext =
          new ClassPathXmlApplicationContext( "meinremotepckg/client/remote-client.xml" );
    
        MeinRemoteDienstIf lk = (MeinRemoteDienstIf) appContext.getBean( "idMeinLocalDienst" );
        MeinRemoteDienstIf rm = (MeinRemoteDienstIf) appContext.getBean( "idMeinRemoteDienstRMI" );
        MeinRemoteDienstIf hi = (MeinRemoteDienstIf) appContext.getBean( "idMeinRemoteDienstHttpInvoker" );
        MeinRemoteDienstIf hs = (MeinRemoteDienstIf) appContext.getBean( "idMeinRemoteDienstHessian" );
        MeinRemoteDienstIf bl = (MeinRemoteDienstIf) appContext.getBean( "idMeinRemoteDienstBurlap" );
        MeinRemoteDienstIf sp = (MeinRemoteDienstIf) appContext.getBean( "idMeinRemoteDienstSoap" );
    
        System.out.println( "\n\nZeit fuer 1000 mal Lesen und Schreiben:" );
        testRemoteConnection( lk );
        testRemoteConnection( rm );
        testRemoteConnection( hi );
        testRemoteConnection( hs );
        testRemoteConnection( bl );
        testRemoteConnection( sp );
      }
    
      private static void testRemoteConnection( MeinRemoteDienstIf dienst )
      {
        long before = System.currentTimeMillis();
        for( int i=0; i<1000; i++ ) {
          String s = "Dies ist mein neuer Test-String " + i;
          dienst.setMyString( s );
          if( !s.equals( dienst.getMyString() ) ) {
            System.out.println( "Fehler: '" + s + "' != '" + dienst.getMyString() + "'" );
            break;
          }
        }
        System.out.println( "" + ((System.currentTimeMillis() - before) / 1000.) + "s " + dienst );
      }
    }
    
  4. Erzeugen Sie im Package-Verzeichnis 'src/meinremotepckg.client' folgende Implementierungsdatei 'MeinLocalDienstImpl.java':

    package meinremotepckg.client;
    
    public class MeinLocalDienstImpl implements meinremotepckg.MeinRemoteDienstIf
    {
      private String myString;
      public  String getMyString() { return myString; }
      public  void   setMyString( String myString ) { this.myString = myString; }
      public  String toString() { return "MeinLocalDienstImpl, last string = " + myString; }
    }
    
  5. Erzeugen Sie im Package-Verzeichnis 'src/meinremotepckg.client' folgende Properties-Datei 'remote-client.properties' und tragen Sie darin die korrekte IP-Adresse Ihres Servers ein (wenn Client und Server auf dem gleichen Rechner laufen, können Sie auch 'server.ip=localhost' setzen):

    server.ip=192.168.0.25
    
  6. Erzeugen Sie im Package-Verzeichnis 'src/meinremotepckg.client' folgende XML-Konfigurationsdatei 'remote-client.xml':

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
      <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="meinremotepckg/client/remote-client.properties" />
      </bean>
      <bean id="idMeinLocalDienst" class="meinremotepckg.client.MeinLocalDienstImpl">
      </bean>
      <bean id="idMeinRemoteDienstRMI"
            class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
        <property name="serviceInterface" value="meinremotepckg.MeinRemoteDienstIf" />
        <property name="serviceUrl" value="rmi://${server.ip}:1099/MeinRemoteDienstName" />
      </bean>
      <bean id="idMeinRemoteDienstHttpInvoker"
            class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
        <property name="serviceInterface" value="meinremotepckg.MeinRemoteDienstIf" />
        <property name="serviceUrl" value="http://${server.ip}:8080/MeineWebApp/MeinRemoteDienstHttpInvoker" />
      </bean>
      <bean id="idMeinRemoteDienstHessian"
            class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
        <property name="serviceInterface" value="meinremotepckg.MeinRemoteDienstIf" />
        <property name="serviceUrl" value="http://${server.ip}:8080/MeineWebApp/MeinRemoteDienstHessian" />
      </bean>
      <bean id="idMeinRemoteDienstBurlap"
            class="org.springframework.remoting.caucho.BurlapProxyFactoryBean">
        <property name="serviceInterface" value="meinremotepckg.MeinRemoteDienstIf" />
        <property name="serviceUrl" value="http://${server.ip}:8080/MeineWebApp/MeinRemoteDienstBurlap" />
      </bean>
      <bean id="idMeinRemoteDienstSoap"
            class="org.codehaus.xfire.spring.remoting.XFireClientFactoryBean">
        <property name="serviceClass" value="meinremotepckg.MeinRemoteDienstIf" />
        <property name="wsdlDocumentUrl" value="http://${server.ip}:8080/MeineWebApp/MeinRemoteDienstSoap?WSDL" />
      </bean>
    </beans>
    

Teil 4: Ausführung

  1. Starten Sie Tomcat.
    Überprüfen Sie Tomcat durch Aufruf von http://localhost:8080 bzw. http://192.168.0.25:8080.
  2. Öffnen Sie ein Kommandozeilenfenster auf dem Server-Rechner, verzweigen Sie in das Projektverzeichnis 'SpringRemoteHttp-Srvr' und führen Sie folgende Kommandos aus:

    cd \MeinWorkspace\SpringRemoteHttp-Srvr

    ant -Dappserver.home=%CATALINA_HOME% deploy-war

    Falls Sie auf einen entfernten Unix- oder Linux-Server deployen wollen: Beachten Sie die Hinweise zu 'PuTTY' und 'PSCP'.

    Beobachten Sie die Konsole von Tomcat. Es dürfen keine Fehler gemeldet werden.

    Wenn Tomcat vollständig gestartet ist, muss unter http://localhost:8080/MeineWebApp/MeinRemoteDienstSoap?WSDL die generierte WSDL-Datei des SOAP Web Services angezeigt werden.

  3. Öffnen Sie ein zweites Kommandozeilenfenster auf dem Server, verzweigen Sie in das Projektverzeichnis 'SpringRemoteRmi' und führen Sie folgende Kommandos aus:

    cd \MeinWorkspace\SpringRemoteRmi

    set CLASSPATH=src;bin;lib/commons-logging.jar;lib/spring.jar

    javac -d bin src/meinremotepckg/server/*.java

    java meinremotepckg.server.MainSrvr

  4. Öffnen Sie (innerhalb der 35 Sekunden, die der RMI-Server läuft) ein Kommandozeilenfenster auf dem Client-Rechner (dies kann auch der gleiche Rechner wie der Server sein), verzweigen Sie in das Projektverzeichnis 'SpringRemoteHttp-Clnt' und führen Sie folgende Kommandos aus:

    cd \MeinWorkspace\SpringRemoteHttp-Clnt

    ant

  5. Sie erhalten eine Ausgabe ähnlich zu:

    Zeit fuer 1000 mal Lesen und Schreiben:
    0.01s MeinLocalDienstImpl, last string = Dies ist mein neuer Test-String 999
    1.59s RMI invoker proxy for service URL [rmi://192.168.0.25:1099/MeinRemoteDienstName]
    2.61s HTTP invoker proxy for service URL [http://192.168.0.25:8080/MeineWebApp/MeinRemoteDienstHttpInvoker]
    1.12s HessianProxy[http://192.168.0.25:8080/MeineWebApp/MeinRemoteDienstHessian]
    1.21s BurlapProxy[http://192.168.0.25:8080/MeineWebApp/MeinRemoteDienstBurlap]
    29.1s XFireProxy[http://192.168.0.25:8080/MeineWebApp/MeinRemoteDienstSoap]
    

Teil 5: Bemerkungen

  1. Weiteres zur Hessian erfahren Sie unter: http://www.caucho.com/hessian.
  2. Weiteres zur XFire-Konfiguration für Spring erfahren Sie unter: http://xfire.codehaus.org/Spring und http://xfire.codehaus.org/Spring+Remoting.




Weitere Themen: andere TechDocs | EJB | SQL | Hibernate
© 1998-2007 Torsten Horn, Aachen