Einfaches Spring HTTP Remoting Beispiel

Ich verwende diesen Blogeintrag, um anhand eines einfachen Beispiels die Verwendung des HTTP-Remoting des Spring Framework zu demonstrieren. Zu diesem Thema gibt es zahlreiche Online-Ressourcen. Daher möchte ich hier eine äußerst einfache, aber vollständige Demonstration der Verwendung von HTTP Remoting von Spring mit Nicht-Browser-Clients bereitstellen.

Der Spring-Ansatz für HTTP-Remoting ermöglicht es Clients, über HTTP mit dem von Spring gehosteten Servercode zu kommunizieren, ohne dass der Clientcode Kenntnisse über die Verwendung von HTTP erfordert. Stattdessen "sieht" der Client-Java-Code nur normale geschäftsbezogene Java-Objekte (normalerweise Schnittstellen) und keine HTTP-spezifischen Objekte.

Spring HTTP Remoting erfordert im Allgemeinen Spring und Java sowohl auf der Server- als auch auf der Clientseite. Wenn diese beiden Anforderungen jedoch erfüllt werden können, kann Spring HTTP Remoting problemlos angewendet werden.

Die folgenden Schritte ermöglichen die HTTP-Kommunikation zwischen von Spring gehosteten Clients und Servern. Nachdem ich die Schritte zuerst kurz skizziert habe, werde ich sie dann genauer untersuchen (einschließlich Codebeispiele).

  1. Erstellen oder verwenden Sie eine vorhandene Spring Bean, die normalerweise eine Java-Schnittstelle implementiert.

    Dies ist nichts Besonderes für das HTTP-Remoting und der gleiche Schritt, den Sie ausführen müssen, um die meisten Dinge im Frühjahr zu erledigen (eine bemerkenswerte Ausnahme ist

    Frühling JDBC

    dafür müssen keine Frühlingsbohnen verwendet werden).

  2. Erstellen Sie die Spring XML-Konfigurationsdatei, um die in Schritt 1 erstellte Bean einem Spring-Anwendungskontext zuzuordnen.

    Wie bei Schritt 1 ist diese XML-Datei nichts Besonderes für Spring HTTP Remoting, sondern gilt für fast alle Spring Framework-Verkabelungen und -Konfigurationen.

  3. web.xmlDatei erstellen oder zur Datei hinzufügen .

    Dieser dritte Schritt ist der erste Schritt, der sich speziell auf Spring HTTP Remoting bezieht, aber dennoch allgemein anwendbar ist

    Spring MVC Framework

    . Dieser Schritt umfasst das Hinzufügen der Servlet-Klassen- und URL-Zuordnungen, wie sie normalerweise verwendet werden

    Java EE

    Servlets

    und

    JavaServer-Seiten

    . Der wichtigste Teil dieses Schritts ist die Angabe der Feder

    DispatcherServlet

    . Hier ist auch ein optionaler "Link" vorgesehen

    web.xml

    Datei an einen Kontextkonfigurationsspeicherort, an dem sich eine oder mehrere Spring XML-Anwendungskontextdateien befinden und verwendet werden.

  4. Erstellen Sie die Spring-spezifische Servlet-Kontextdatei.

    Diese XML-Datei ähnelt stark einer "normalen" Spring-Anwendungskontext-XML-Konfigurationsdatei, ihr Name wird jedoch durch die Konvention des Servlet-Namens gefolgt von einem Bindestrich und dem Wort Servlet vorgegeben. Mit anderen Worten, wenn das Servlet in der "irgendwo" genannt wurde

    web.xml

    Datei, diese Spring-Servlet-Konfigurationsdatei würde aufgerufen

    somewebthing-servlet.xml

    . Diese Datei enthält die Konfiguration für die

    HttpInvokerServiceExporter

    (der Teil davon, der sich speziell auf das in diesem Blogeintrag behandelte HTTP-Remoting bezieht) und URL-Zuordnungsinformationen.

  5. Prüfung!

    Obwohl der einfache Client ohne HTTP schreibt und anscheinend nur Java-Objekte verwendet, ruft er den Dienst tatsächlich über HTTP auf. Dies wird "bewiesen", indem der Client ohne den bereitgestellten Dienst ausgeführt wird und nach dem resultierenden HTTP-Fehlercode gesucht wird.

Ich werde nun die obigen Schritte detaillierter demonstrieren und versuchen, sie mit Codebeispielen konkret zu veranschaulichen.

Schritt 1: Die Bohne und ihre Schnittstelle

Dieser Schritt unterscheidet sich nicht von der Definition von Java-Klassen und -Schnittstellen, die sie für die Verwendung mit Spring implementieren. Die folgenden Codelisten zeigen die für dieses Beispiel verwendete Schnittstelle ( StateCapitalServiceIF) und die implementierende Klasse ( StateCapitalService).

--- StateCapitalServiceIF.java ---

package examples.springhttp; import java.io.Serializable; /** * The State Capital Service interface that the client will use to access * server-side functionality via HTTP. */ public interface StateCapitalServiceIF extends Serializable { /** * Provide capital of state whose name is provided. * * @param stateName Name of state whose capital is desired. * @return Capital of the specified state; null if not found. */ public String getCapital(final String stateName); } 

--- StateCapitalService.java ---

package examples.springhttp; import java.util.Map; /** * Implementation of functionality to be run after being called by client via * HTTP. */ public class StateCapitalService implements StateCapitalServiceIF { Map statesAndCapitals = null; public StateCapitalService() { } /** * Set my states to state capitals mapping. * * @param statesAndCapitals States to state capitals mapping. */ public void setStatesAndCapitals(final Map statesAndCapitals) { this.statesAndCapitals = statesAndCapitals; } /** * Provide capital of state whose name is provided. * * @param stateName Name of state whose capital is desired. * @return Capital of the specified state; null if not found. */ public String getCapital(final String stateName) { return this.statesAndCapitals.get(stateName); } } 

Schritt 2: Spring Application Context-Konfigurationsdatei

Ich möchte die HTTP-spezifische Konfiguration von Spring von der XML-Konfiguration der Bean trennen. Daher ist die Konfiguration der Bohne genau so, wie man es normalerweise bei Spring sehen würde. Um die StateCapitalServiceobige Klasse zu konfigurieren , wird die folgende Konfiguration verwendet:

--- spring-http-config.xml ---


    

So far, nothing specific to HTTP Remoting has been done. In fact, the bean, its interface, and its XML application context configuration could all be run by a normal Java SE class like the one shown below:

--- MainServiceAppContext.java ---

package examples.springhttp; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Demonstrates how Spring bean can be used without any HTTP involvement. */ public class MainServiceAppContext { public static void printStateInfo( final StateCapitalServiceIF stateCapitalMapper, final String state) { System.out.println( "The capital of " + state + " is " + stateCapitalMapper.getCapital(state)); } /** * @param args the command line arguments */ public static void main(String[] args) { final ApplicationContext context = new ClassPathXmlApplicationContext( "examples/springhttp/spring-http-config.xml" ); StateCapitalServiceIF stateCapitalMapper = (StateCapitalServiceIF) context.getBean("stateCapitalService"); printStateInfo(stateCapitalMapper, "Alabama"); printStateInfo(stateCapitalMapper, "Colorado"); } } 

Step #3: The web.xml File

This web.xml file is familiar to anyone who has developed a Java EE web application. The web.xml used in this example is shown next.


    
      Simple Spring HTTP Remoting Example This is meant as an extremely simple example of using Spring's HTTP Remoting capability. statesCapitals org.springframework.web.servlet.DispatcherServlet 1 statesCapitals /statesCapitals org.springframework.web.context.ContextLoaderListener contextConfigLocation /WEB-INF/examples/springhttp/spring-http-config.xml 
    

Step #4: The Servlet Context Configuration File

Because the servlet in this example is named "statesCapitals," a Spring servlet configuration file named statesCapitals-servlet.xml needs to be provided. It is shown next:

--- statesCapitals-servlet.xml ---


    
      examples.springhttp.StateCapitalServiceIF httpStateCapitalService 
    

Step #5: Testing It

Wir müssen den Client so konfigurieren, dass er über HTTP mit unserer serverseitigen Anwendung kommuniziert. Die Konfiguration hierfür ist in spring-http-client-config.xmldiesem Beispiel enthalten und wird als Nächstes gezeigt:

--- spring-http-client-config.xml ---


    
      //localhost:8080/SpringHTTPExample/statesCapitals examples.springhttp.StateCapitalServiceIF 
    

Der Client-Code, der das obige XML verwendet, um einen Spring-Container zu booten und den serverseitigen Code über HTTP aufzurufen, befindet sich in der Klasse. Dieser HttpClientCode wird als Nächstes angezeigt:

--- HttpClient.java ---

package examples.springhttp.client; import examples.springhttp.StateCapitalServiceIF; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * This class demonstrates a client of a Spring HTTP-exposed service and shows * how the client interacts with the server as if using normal Java objects * rather than using anything HTTP specific. */ public class HttpClient { public static void printStateInfo( final StateCapitalServiceIF stateCapitalMapper, final String state) { System.out.println( "The capital of " + state + " is " + stateCapitalMapper.getCapital(state)); } public static void main(final String[] arguments) { final ApplicationContext context = new ClassPathXmlApplicationContext( "examples/springhttp/client/spring-http-client-config.xml"); final StateCapitalServiceIF stateCapitalService = (StateCapitalServiceIF) context.getBean("stateCapitalProxyService"); printStateInfo(stateCapitalService, "Colorado"); printStateInfo(stateCapitalService, "Alabama"); } }