|
Lo scopo del lavoro è quello di guadagnarsi il tempo libero
|
|
| Home Page |
|
| Articoli |
|
| News |
|
| Forum |
|
| Classi |
|
|
|
|
|
Esporre un POJO con Spring
By
Alessandro Gambaro
28 gennaio 2008
|
 |
|
In questo articolo ci proponiamo di mostrare, con un esempio pratico, le potenzialità che Spring offre per l’esposizione dei servizi. Dopo una breve introduzione alle varie possibilità di remoting, verrà presentato un esempio di esposizione di un POJO. Lo stesso POJO verrà esposto utilizzando diversi protocolli senza che il codice dello stesso venga intaccato, se non in minima parte con alcune annotations. L’articolo si occuperà delle potenzialità di Spring inerenti il remoting, ma non verranno analizzati i protocolli ne tanto meno i software utilizzati per l’esposizione del POJO. Per questo motivo, per la sua piena comprensibilità, è necessario che l’utente possegga già le conoscenze di base delle tecnologie utilizzate per l’esposizione dei servizi (cioè abbia idea di cosa si intenda con RMI e WS) e di Spring.
|
|
|
Spring Remoting
|
top
|
|
Remoting è una conversazione tra un Client ed un servizio remoto, il client necessita di servizi che non possiede e deve quindi chiedere un supporto all’esterno del sistema locale, necessita quindi di un servizio remoto che possa soddisfare le sue esigenze. Supponiamo, ad esempio, di dover gestire un negozio virtuale: durante il check-out, se il customer decide di effettuare un pagamento con carta di credito, occorrerà verificare la veridicità dei dati e la disponibilità del credito, il tutto ovviamente non è disponibile nei database del negozio, ma generalmente è un servizio remoto offerto ed esposto in vari modi, ad esempio via WS, RMI...
Il Remoting di Spring supporta diverse tecnologie che possono essere applicate ad un semplice POJO per renderlo disponibile a terzi.
Attualmente, gennaio 2008, Spring 2.5 supporta le seguenti tecnologie:
- Remote Method Invocation (RMI)
- Spring's HTTP invoker
- Caucho Hessian, Burlap
- JAX RPC
- JMS
Indipendentemente dal modello che si sceglierà per esporre i servizi, vedremo che Spring ci permetterà di passare da uno all'altro senza problemi! Infatti tutti i modelli hanno lo stesso comune denominatore, in alcuni casi sono completamente simili (soprattutto nel caso di accessing via client). Una volta compresi i meccanismi per esporre un servizio con RMI, sarà molto facile e veloce riuscire ad esporlo anche via WS o Hessian.
|
|
Due parole sull’esempio...
|
top
|
|
L’esempio che presenteremo riguarda un servizio di echo (applicativo che prende in ingresso un stringa e la restiruisce aggiungendo alla fine la data di ricezione della stessa), esposto con RMI, WS, Hessian, Burlap e Spring’http. Per poter esporre il servizio con WS ci si appoggerà ad Xfire (versione 1.2.6) con uso della JSR-181, in modo da utilizzare le annotation (si è scelto di utilizzare le annotation in modo da poter ridurre la quantità di XML).
Per agevolare l’utente, verrà fornito il codice completo di librerie e un basico build.xml, che potrà essere utilizzato, oltre che per la compilazione dello stesso codice, anche per la generazione in un war.
L’ambiente di sviluppo/testing utilizzato è così composto:
- JDK 1.5
- Apache Tomcat/5.5.25
- ANT 1.7
- Eclipse Europa
- SpringIDE
|
|
Il POJO
|
top
|
Il POJO utilizzato si basa su due file, una classe che implementa la seguente interfaccia:
public interface EchoService { public String printback(java.lang.String name); }
public class EchoServiceImpl implements EchoService { ... }
Come primo step occorre far si che Spring conosca l’esistenza della classe , a tale scopo creiamo un primo file di configurazione XML che chiameremo spring-context.xml dove definiremo il nostro bean:
<bean id="echoService" class="com.javaportal.ale.myPojos.EchoServiceImpl"/>
Siccome vogliamo realizzare un’applicazione WEB, creeremo anche un web.xml che per il momento sarà vuoto.
|
|
Esporre con RMI
|
top
|
|
Iniziamo la nostra analisi occupandoci dell'esposizione con l'uso di RMI.
Per evitare di sporcare il context base di Spring, creiamo adesso un nuovo file di configurazione XML, relativo al solo servizio RMI e lo nominiamo “rmi-context.xml”. Di seguito il codice necessario per esporre uno Spring bean con RMI:
<bean class="org.springframework.remoting.rmi.RmiServiceExporter"> <property name="service" ref="echoService"/> <property name="serviceName" value="rmiEchoService"/> <property name="serviceInterface" value="com.javaportal.ale.myPojos.EchoService"/> </bean>
Abbiamo appena creato un bean che fa riferimento ad un oggetto di Spring, tramite il parametro "service" gli abbiamo detto a quale bean deve fare riferimento, tramite il parametro "serviceName " quale sarà il nome utilizzato dal protocollo RMI e tramite il parametro "serviceInterface" a quale interfaccia dovrà fare riferimento.
Anche questo file di configurazione XML andrà aggiunto nel file web.xml per permettere a Spring di creare il corretto contesto (NOTA: RMI , a differenza degli altri servizi di cui ci occuperemo in questo articolo, non ha bisogno di servlet, quindi può essere usato anche caricando lo Spring Context "spring-context.xml, rmi-context.xml" da un main senza la necessità di un web.xml).
A questo punto il nostro lavoro per l'esposizione di un servizio tramite RMI è terminato!
|
|
Esporre con Hessian, Burlap, Spring’sHttp
|
top
|
|
Hessian e Burlap sono entrambi soluzioni di Caucho, mentre Spring'sHttp è proprietario di Spring. Il protocollo Hessian si basa sullo scambio di messaggi binari ma a differenza di RMI che si limita a Java, questi sono portabili ad altri linguaggi, come C, C++, Python e altri.
Il protocollo Burlap scambia messaggi in formato XML e questo li rende portabili ad ogni linguaggio, oltre che renderli facilmente leggibili.
Spring's Http permette il remoting su protocollo HTTP ed usa la serialization come RMI.
Benché queste soluzioni siamo molto diverse, il loro utilizzo con l'ausilio delle librerie di Spring risulta essere molto simile. Analizzeremo nel dettaglio solo l'esposizione con Hessian, lasciando a voi il compito di trovare le differenze nel codice di esempio allegato all’articolo.
Sembrerà strano, ma l'esposizione di un servizio con Hessian tramite Spring è simile all’esposizione con RMI. Come primo step occorre configurare un exporter bean, basato sulla classe HessianServiceExporter, cioè uno Spring MVC Controller con il compito di ricevere le richieste http e trasformarle in chiamate ai corretti metodi.
<bean name="hessianEchoService" class="org.springframework.remoting.caucho.HessianServiceExporter"> <property name="service" ref="echoService"/> <property name="serviceInterface" value="com.javaportal.ale.myPojos.EchoService"/> </bean>
Possiamo notare che per una corretta configurazione del bean si devono utilizzare:
- la property "service", che fa riferimento al bean che si vuole esporre
- un’l'interfaccia, tramite la property "serviceInterface"
Anche in questa caso creeremo un nuovo file che chiameremo hessianBurlapHttp-servlet.xml, nel quale collocare le configurazioni sopra descritte, il nome di questo file non è casuale ma legato al nome della servlet (che definiremo a breve).
A questo punto si deve notare che Hessian e' un servizio http, il quale usa uno Spring MVC Controller, ne deriva che occorrerà fare altre due configurazioni per completare l'esposizione:
- configurare una Spring DispatcherServlet nel web.xml
- configurare una URL handler
Per iniziare andremo a modificare il file web.xml ed aggiungeremo il codice necessario per la definizione della DispatcherServlet.
<servlet> <servlet-name>hessianBurlapHttp</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>hessianBurlapHttp</servlet-name> <url-pattern>*.hessianService</url-pattern> </servlet-mapping>
Per terminare andremo a definire l'URL Handler per permettere a Spring di mappare l'url con il giusto exporter.
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/echo.hessianService">hessianEchoService</prop> </property> </bean>
Con queste poche righe di configurazione abbiamo appena esposto un servizio Hessain che risponde alla seguente url: http://myHost/myContextPath/echo.hessianService.
Tutto e' stato costruito in modo estremamente semplice veloce e soprattutto senza aver bisogno di conoscere le librerie Caucho! Inoltre se volessimo passare ad uno degli altri due servizi le modifiche sarebbero minime.
|
|
Esporre con WS tramite XFire
|
top
|
|
A differenza delle sopra descritte esportazioni, per quanto riguarda WS , Spring non mette a disposizione nessun exporter; in questo caso ci appoggeremo infatti a XFire, inoltre a differenza di quello che abbiamo fatto precedentemente, utilizzeremo le annotations e quindi le specifiche relative alla JSR-181.
Partiamo con l'inserimento delle annotations nel codice, andremo ad utilizzare solo quelle necessarie per l'esposizione base, anche se la JSR-181 permette configurazioni più precise di queste:
@WebService(targetNamespace = "http://myHost/ myContextPath/services/ EchoService") public interface EchoService { public String printback(java.lang.String name); }
@WebService(serviceName = "EchoService", endpointInterface = com.javaportal.ale.myPojos.EchoService") public class EchoServiceImpl implements EchoService { Logger logger = Logger.getLogger(getClass()); public String printback(@WebParam(name = "text") String text) { ... }
Adesso non ci rimane che creare l'XML che ci permetterà di legare assieme tutti i pezzi per concludere l'esposizione del servizio.
Considerato che si tratta di un servizio basato su HTTP, anche in questo caso come è successo per Hessian, andremo a definire la servlet che si occuperà di gestire le chiamate legate a XFire, modificando il web.xml ed aggiungendo la definizione di una XFireSpringServlet:
<servlet> <servlet-name>XFireServlet</servlet-name> <servlet-class> org.codehaus.xfire.spring.XFireSpringServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>XFireServlet</servlet-name> <url-pattern>/servlet/XFireServlet/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>XFireServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
Similmente all’esposizione Hessian dobbiamo configurare un Handler, in questo caso si dovrà notare che si sta utilizzando la JSR-181, perciò non sarà un SimpleUrlHandlerMapping ma invece un Jsr181HandlerMapping.
Per non compromettere (cerchiamo di lavorare in modo pulito) lo Spring Context, creeremo un nuovo file di configurazione per XFire che chiameremo xfire-context.xml dove inseriremo il seguente codice:
<bean id="webAnnotations" class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations" />
<bean id="jsr181HandlerMapping" class="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping"> <property name="typeMappingRegistry" ref="xfire.typeMappingRegistry" /> <property name="xfire" ref="xfire" /> <property name="webAnnotations" ref="webAnnotations" /> </bean>
La prima property "xfire" è un riferimento all'handler di XFire che viene caricato tramite il file di configurazione xfire.xml di XFire, che aggiungeremo nel web.xml. La seconda property webannotation dichiara all'handler di utilizzare la JSR-181 per il mappaggio dei beans tramite le annotations.
Abbiamo così terminato, siamo pronti per effettuare il deploy e al seguente url: http://myHost/myContextPath/services/EchoService?wsdl possiamo finalmente vedere il nostro WSDL!
|
|
Codice dei clients
|
top
|
|
A corredo di questo articolo sono presenti i clients per effettuare le chiamate ai nostri nuovi servizi. Come avrete modo di constatare voi stessi il codice java dei clients è del tutto identico, ovviamente cambia lo Spring Context che viene caricato :). In aggiunta per RMI ho inserito anche il codice che effettua la chiamata senza l'ausilio dello Spring Context, in modo da notare l’utilizzo di questo stub: RmiInvocationWrapper_Stub che fa parte delle librerie di Spring Download del codice dei clientis
|
|
Riferimenti
|
top
|
[1] Spring IN ACTION - Second Edition - Craig Walls [2] The Spring Framework - Reference Documentation - Version 2.5 [3] XFire documentation [4] Caucho documentation [5] Spring Framework [6] http://springtips.blogspot.com
|
|
|

Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati sotto licenza Creative Commons
|
|
|