Immaginiamo di dover leggere dei file da un server FTP, effettuare alcune modifiche ed inviarli ad un Web Service REST.
Uno dei concetti base di Spring Integration sono i channels: si tratta dei canali dentro ai quali i producer possono inserire dei dati che verranno poi letti dai consumer.
Tornando al nostro esempio, sarà necessario utilizzare tre canali: uno contenente i file dell’FTP, uno avente il contenuto dei suddetti file ed uno avente gli oggetti deserializzati.
<int:channel id="ftpFiles"/>
<int:channel id="fileContent"/>
<int:channel id="xmlObjects"/>
Ipotizziamo di aver un server FTP dentro la nostra rete locale, al suo interno ci sarà una directory di test che conterrà i file che vogliamo far leggere al sistema. Sarà dunque necessario creare un Adapter che leggerà il contenuto dei file per poi copiarli localmente (gli adapter sono necessari per connettere i channel con delle fonti esterne).
Prima di tutto creiamo un bean avente come proprietà i dati di accesso al server FTP. L’adapter copierà in locale i file XML trovati nella cartella remota, rinominandoli durante il processo. Fatto ciò, invierà un messaggio con il contenuto di un file al canale ftpFiles. Per schedulare queste “scansioni” è necessario utilizzare un Poller, per semplicità ne è stato creato uno di default (utilizzato da tutti i bean).
L’esecuzione avverrà ogni secondo e invierà un massimo di 5 messaggi per volta.
<bean id="ftpClientFactory" class="org.springframework.integration.ftp.session.DefaultFtpSessionFactory">
<property name="host" value="localhost"/>
<property name="port" value="21"/>
<property name="username" value="user"/>
<property name="password" value="password"/>
</bean>
<int-ftp:inbound-channel-adapter id="ftpInbound"
channel="ftpFiles"
filename-pattern="*.xml"
session-factory="ftpClientFactory"
auto-create-local-directory="true"
delete-remote-files="true"
local-filename-generator-expression=
"'ftpupload.' + T(java.lang.System).currentTimeMillis() + '.txt'"
remote-directory="/test"
local-directory="/tmp ">
</int-ftp:inbound-channel-adapter>
<int:poller id="defaultPoller" default="true" max-messages-per-poll="5" fixed-rate="1000"/>
Verrà poi utilizzato un Trasformer standard capace di trasformare il contenuto dei file in stringhe, si noti che i dati vengono prelevati dal canale ftpFiles ed inseriti in quello fileContent.
Infine, è necessario effettuare l’unmarshaling delle stringhe all’interno di oggetti JAXB2. Attenzione: il numero degli elementi nella proprietà classesToBeBound deve corrispondere al numero degli elementi nello schema (anche l’ordine è importante).
Al termine della trasformazione, gli oggetti vengono inviati al terzo canale.
<bean id="xmlMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>org.springframework.oxm.jaxb.Flight</value>
<value>org.springframework.oxm.jaxb.Flights</value>
</list>
</property>
<property name="schema" value="classpath:com/example/xsd/schema.xsd"/>
</bean>
<int-xml:unmarshalling-transformer unmarshaller="xmlMarshaller" input-channel="fileContent" output-channel="xmlObjects" />
Infine effettuiamo la stampa degli oggetti per verificare che sia andato tutto a buon fine.
<int-stream:stdout-channel-adapter id="stdoutAdapterWithDefaultCharset" channel="xmlObjects"/>