Vamos a desarrollar un ejemplo donde se cargará una lista desplegable con países, y otra dependiente de esta con ciudades. Para ello necesitaremos un Spring Java Bean (CitiesManagerBean) con dos métodos getCountries() y getCities(), que daremos de alta el fichero de configuración de Spring.
<?xml version="1.0" enconding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans> <!-- Cities Manager Bean --> <bean id="citiesManagerBean" class="examples.ajax.ui.CitiesManagerBean" /> </beans>
Tambien habrá que crear un objeto (ListItem) para la transferencia de datos (DTO) y declarar ambos objetos en el fichero /WEB-INF/dwr.xml
<?xml version="1.0" enconding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead LImited//DTD Direct Web Remoting 2.0//EN" "http://www.getahead.ltd.uk/dwr//dwr20.dtd">
<dwr>
<allow>
<create creator="spring" javascript="citiesManager">
<param name="beanName" value="citiesManagerBean" />
<include method="getCountries" />
<include method="getCities" />
</create>
<convert converter="bean" match="examples.ajax.ui.ListItem" />
</allow>
</dwr>Veamos la implementación de CitiesManagerBean:
package examples.ajax.ui;
import java.util.ArrayList;
import java.util.List;
public class CitiesManagerBean {
Object[] countries = null;
Object[] cities = null;
public Object[] getCountries () {
return countries;
}
public Object[] getCities (String countryId) {
List list = new ArrayList();
for (int i = 0; i < cities.length; i++) {
ListItem item = (ListItem) cities[i];
if (item.getKey().equals(countryId)) {
list.add(item);
}
}
return list.toArray();
}
private void initializeCountries() {
List list = new ArrayList();
ListItem item = new ListItem("01", "España");
list.add(item);
item = new ListItem("02", "Francia");
list.add(item);
item = new ListItem("03", "Italia");
list.add(item);
countries = list.toArray();
}
private void initializeCities () {
List list = new ArrayList();
list.add(new ListItem("01", "Madrid"));
list.add(new ListItem("01", "Barcelona"));
list.add(new ListItem("01", "Coruña"));
list.add(new ListItem("02", "Paris"));
list.add(new ListItem("02", "Marsella"));
list.add(new ListItem("02", "Lion"));
list.add(new ListItem("03", "Roma"));
list.add(new ListItem("03", "Venecia"));
list.add(new ListItem("03", "Milan"));
cities = list.toArray();
}
public CitiesManagerBean () {
initializeCountries();
initializeCities();
}
}Implementación de ListItem:
package examples.ajax.ui;
public class ListItem {
private String key = null;
private String value = null;
public ListItem (String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() { return key; }
public void setKey(String key) { this.key = key; }
public String getValue() { return value; }
public void setValue(String value) { this.value = value; }
}Esta clase de DTO será la encargada de envolver los datos que se intercambian entre cliente y servidor.
Un Bean converter es un tipo de conversor encargado de transformar POJOs en arrays de Javascript y viceversa.
La página de nuestra aplicación deberá incluir el javascript necesario para acceder añ Bean citiesManagerBean a través de su javascript asociado citiesManager.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Ajax Test Page</title>
<script type="text/javascript" src="/neo-examples/dwr/interface/citiesManager.js"></script>
<script type="text/javascript" src="/neo-examples/dwr/engine.js"></script>
<script type="text/javascript" src="/neo-examples/dwr/util.js"></script>
<script>
function loadCountries() {
citiesManager.getCountries(fillCountries);
}
function fillCountries() {
DWRUtil.addOptions("countries", data, "key", "value");
}
function loadCities() {
DWRUtil.removeAllOptions("cities");
citiesManager.getCities(fillCities, DWRUtil.getValue("countries"));
}
function fillCities (data) {
DWRUtil.addOptions("cities", data, "key", "value");
}
</script>
</head>
<body>
<select id="countries" onChange="loadCities();"></select>
<select id="cities"></select>
</body>
</html>La primer funcion, loadCountries(), la llamaremos al inicio de la página, dentro del onLoad del body. Al ejecutarse, llamará al método getCountries() de citiesManager y el resultado lo tendremos en la función que le pasemos como parámetro, en este caso Countries().
Dentro de fillCountries() utilizaremos la función DWRUtil.addOptions para rellenar la lista desplegable cuyo id es countries con la lista de datos recibidos, diciéndole que propiedad corresponde al código y cuál a la descripción.
Análogamente, la función loadCities() estará en el onChange de la lista countries, y cuando se ejecute (cada vez que cambiemos de país) borrará todas las opciones de la lista cities y ejecutará el método getCities(), pasando como parámetro el value de la lista countries (el país elegido).
Si todo ha sido configurado correctamente, el resultado será una lista desplegable de países que se llena al cargar la página y una lista desplegable de ciudades que se refresca cada vez que cambiamos la primera, todo ello sin que se refresque la página.


Tenemos a nuestra disposición la url http://localhost:8080/[Mycontext]/dwr del contexto de nuestra aplicación donde poder probar, conocer el estado y el funcionalidad de cada uno de las clases javascript generadas por DWR.
