Exemple de communication à distance HTTP Spring simple

J'utilise cette entrée de blog pour démontrer par un exemple simple l'utilisation de HTTP Remoting de Spring Framework. Il existe de nombreuses ressources en ligne sur ce sujet, donc mon intention ici est de fournir une démonstration extrêmement simple mais complète de l'utilisation de HTTP Remoting de Spring avec des clients non-navigateur.

L'approche Spring de HTTP Remoting permet aux clients de communiquer avec le code serveur hébergé par Spring via HTTP sans que le code client ne nécessite une quelconque connaissance de HTTP utilisé. Au lieu de cela, le code Java client "voit" uniquement les objets Java liés à l'entreprise normaux (généralement des interfaces) plutôt que des objets spécifiques à HTTP.

Spring HTTP Remoting nécessite généralement Spring et Java à la fois du côté serveur et du côté client. Cependant, si ces deux conditions peuvent être remplies, Spring HTTP Remoting est facilement appliqué.

Les étapes suivantes permettent la communication HTTP entre les clients et les serveurs hébergés par Spring. Après avoir d'abord brièvement décrit les étapes, je les approfondirai plus en détail (y compris des exemples de code).

  1. Créez ou utilisez un bean Spring existant qui implémente généralement une interface Java.

    Cela n'a rien de spécial pour la communication à distance HTTP et c'est la même étape que vous devrez suivre pour faire la plupart des choses au printemps (une exception notable est

    Printemps JDBC

    qui ne nécessite pas l'utilisation de Spring beans).

  2. Créez le fichier de configuration Spring XML pour associer le bean créé à l'étape 1 à un contexte d'application Spring.

    Comme à l'étape 1, ce fichier XML n'a rien de particulier à Spring HTTP Remoting, mais est plutôt commun à presque tous les câblages et configurations de Spring Framework.

  3. Créer ou ajouter au web.xmlfichier.

    Cette troisième étape est la première étape qui est plus particulière à Spring HTTP Remoting, mais qui est toujours généralement applicable avec

    Cadre Spring MVC

    . Cette étape comprend l'ajout de la classe de servlet et des mappages d'URL comme on l'utilise habituellement avec

    Java EE

    servlets

    et

    Pages JavaServer

    . La partie la plus importante de cette étape est de spécifier le ressort

    DispatcherServlet

    . Un "lien" facultatif est également fourni dans ce

    web.xml

    fichier vers un emplacement de configuration de contexte où un ou plusieurs fichiers de contexte d'application Spring XML sont situés et utilisés.

  4. Créez le fichier de contexte de servlet spécifique à Spring.

    Ce fichier XML ressemble beaucoup à un fichier de configuration XML de contexte d'application Spring "normal", mais son nom est prescrit par la convention du nom de servlet suivi d'un hypen et du mot servlet. En d'autres termes, si le servlet s'appelait "somewebthing" dans le

    web.xml

    fichier, ce fichier de configuration du servlet Spring serait appelé

    somewebthing-servlet.xml

    . Ce fichier contient la configuration du

    HttpInvokerServiceExporter

    (l'élément de ceci qui est particulier à HTTP Remoting couvert dans cette entrée de blog) et les informations de mappage d'URL.

  5. Tester!

    Bien que le client simple écrive sans HTTP à l'esprit et semble n'utiliser que des objets Java, il appellera en fait le service via HTTP. Cela sera "prouvé" en exécutant le client sans le service déployé et en surveillant le code d'erreur HTTP résultant.

I'll now move onto demonstrating the above steps in greater detail and attempt to illustrate them concretely with code samples.

Step #1: The Bean and Its Interface

This step is no different than defining Java classes and interfaces they implement for use with Spring. The following code listings show the interface (StateCapitalServiceIF) and the implementing class (StateCapitalService) used for this example.

--- 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); } } 

Step #2: Spring Application Context Configuration File

I like to keep Spring's HTTP-specific configuration separate from the bean's XML configuration. Therefore, the bean's configuration is exactly like one would see normally with Spring. To configure the StateCapitalService class above, the following configuration is used:

--- 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

Nous devons configurer le client pour qu'il communique via HTTP avec notre application côté serveur. La configuration pour cela est contenue dans spring-http-client-config.xmlcet exemple et est illustrée ci-dessous:

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


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

Le code client qui utilise le XML ci-dessus pour amorcer un conteneur Spring et appeler le code côté serveur via HTTP est dans la classe HttpClientet ce code est affiché ensuite:

--- 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"); } }