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).
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).
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.
Créer ou ajouter au
web.xml
fichier.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.
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.
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.xml
cet 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 HttpClient
et 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"); } }