Posts tagged: ajax

Spring Web Flow, DWR: perfect combination !

springDopo un lungo letargo arieccomi qui a parlare di questioni informatiche che trovo prima di tutto molto divertenti (vi chiederete: che tipo è questo?) e dopo molto interessanti. Trovandomi ultimamente occupato allo sviluppo di un applicazione web di cui spero sentirete parlare molto presto, ho provato dapprima e poi ormai adottato la tecnologia messa a disposizione da Spring Web Flow, un framework basato su Spring che permette di definire dei flussi di navigazione per un applicazione web in modo semplice, chiaro e potente…..molto potente. Tralasciamo qui la discussione dei dettagli della tecnologia, per descrivere quello che in sostanza è un integrazione tra SWF, DWR Direct Web Remoting, un framework che aggiunge il supporto AJAX alle nostre applicazioni. Come dicevo, non starò a dettagliare ciò che vogliono dire i file di configurazione, il significato, etc etc, dando tutto per scontato….in futuro se risciro magari, pubblicherò qualche tutorial su Spring framework e spring web flow, anche se in rete si trova di tutto. Ciò detto….let’s start! Occurre naturalmente scaricare la libreria: DWR. Dopo di che si procede con ordine. Sinteticamente, ricordiamo che DWR permette di richiamare attraverso una call-back, dei metodi remoti esposti server side. I risultati restituiti dalla chiamata ai metodi, che possono essere di tipo semplice (int, String, boolean) o complesso come Array di oggetti o di tipi semplice. I risultati vengono "trasformati" e forniti come varibili javascript (array, stringhe o quant’altro) le quali possono essere usati poi localmente. Editiamo il file web.xml aggiungenfo le seguenti linee:

1
2
3
4
5
6
7
8
9
10
11
12
<servlet>
    <servlet-name>dwr</servlet-name>
    <servlet-class>org.directwebremoting.spring.DwrSpringServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>dwr</servlet-name>
    <url-pattern>/dwr/*</url-pattern>
</servlet-mapping>

le quali inizializzano la servlet che permetterà il riconoscimento delle chiamate verso gli script javascript per realizzare l’interazione AJAX. L’integrazione di DWR 2.0 con Spring 2.5 è molto più light rispetto alla versione precedente. Sostanzialmente basta aggiungere il namespace di dwr in testa al file di configurazione globale di spring, definire il controller e qualche mapping di URL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
          http://www.directwebremoting.org/schema/spring-dwr
         http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd">
 
    <dwr:controller id="dwrController" debug="true" />
    <bean id="urlMapping" 
             class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <!-- DWR configuration -->
                <prop key="/dwr/**/*.*">dwrController</prop>
                <prop key="/dwr/**/*">dwrController</prop>
                <prop key="/dwr">dwrController</prop>
                <prop key="*.html">dwrController</prop>
            </props>
        </property>
        <property name="alwaysUseFullPath" value="true"/>
    </bean>
</beans>

Successivamente ci rimane da dichiarare il metodo remoto che si vuole esporre e la eventuale classe che si desidera gestire dal client con javascript. Il tutto si fa dal file xml, che per chiarezza scrivo sempre a parte e poi lo includo in web.xml come facente parte della configurazione.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
File: dwr.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
          http://www.directwebremoting.org/schema/spring-dwr
          http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd">
    <bean id="dwrexposure" class="it.devme.dwr.exposure.DWRExposure">
        <dwr:remote javascript="DWR">
            <dwr:include method="retriveProductCompanyList" />
        </dwr:remote>
        <property name="baseManager"><ref bean="baseManager"/></property>
    </bean>
    <dwr:configuration>
        <dwr:convert type="bean" class="it.devme.dwr.exposure.ProductsVO" />
    </dwr:configuration>
</beans>

Praticamente abbiamo fatto, DWRExposureè la classe che contiene il metodo retriveProductCompanyList che intendiamo esporre, che restituisce un array di oggetti ProductsVO i quali vengono convertiti e resi utilizzabili da locale da DWR, con il tag dwr:convert che indichiamo. L’oggetto ProductsVO è un semplicissimo Java Bean contenente 2 campi che sono l’id del prodotto e la sua descrizione. Da client side, includiamo i seguenti script:

1
2
3
<script type="text/javascript" src="<c:url value="dwr/interface/DWR.js"/>"></script>
<script type="text/javascript" src="<c:url value="dwr/engine.js"/>"></script>
<script type="text/javascript" src="<c:url value="dwr/util.js"/>"></script>

Il primo viene creato da DWR e contiene la logica che permette l’invocazione del metodo remoto e il recupero del risultato. Le altre 2 inclusioni permettono l’utilizzo di alcune funzioni di utilità molto comode. Vediamo ora come fare a usare il tutto. Use case: 2 select, uno che contiene una lista di utenti. L’altro conterrà la lista dei prodotti associati all’utente. La selezione del primo, fa scattare l’invocazione del metodo remoto che riempie il secondo select con i dati dei prodotti associati all’utente selezionato:

1
2
3
4
5
6
7
8
<select name="user_id" id="user_id" onchange="loadProduct();">
    <option value="0">Scegli</option>
    <option value="1">Utente1</option>
    <option value="2">Utente2</option>
</select>
<select name="product_id" id="product_id" >
    <option value="0">Scegli</option>
</select>

Quindi selezionando l’utente dalla lista, verrà richiamato il codice javascript che andremo a scrivere, che richiamerà il metodo remoto:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/** Call Remote method and
load products data */
function loadProduct() {
    var user_id = DWRUtil.getValue("user_id");
    if (user_id>0) {
        DWR.retriveProductsList(user_id, gotProducts);
    } else {
        dwr.util.removeAllOptions("product_id");
        dwr.util.addOptions("product_id", [ { name:'Scegli..', id:'0' } ], "id", "name");
        document.campaign.product_id.disabled=true;
    }
}
function gotProducts(products) {
    dwr.util.addOptions("product_id", products, "idproduct", "name");
    document.campaign.product_id.disabled=false;
}

La prima funzione loadProduct() richiamerà il metodo remoto, selezionando l’utente dall’elemento select attraverso la funzione di utilità DWRUtil.getValue("user_id"). Il metodo richiamato restituirà il risultato alla funziona gotProducts(products) fornendolo come parametro. L’array di oggetti a questo punto, conterrà le informazioni sui prodotti associati all’utente, e può essere assegnato al select dei prodotti attraverso l’altra funzione di utilità dwr.util.addOptions("product_id", products, "idproduct", "name"). E il gioco è fatto…con una semplicità incredibile, senza requirements mostruoso o complessi si aggiunge il supporto ad AJAX alla nostra applicazione Java, in particolare Spring. Con queste informazioni in mani ci si può sbizzarire creando il proprio personale componente AJAX. Nel prossimo articolo vedremo come integrare il supporto per JCaptcha per rendere più sicure le nostre applicazione. Alla prossima.

WordPress Themes