Dienstag, 4. Dezember 2007

Ajax in Action III

Im vorherigen Post aus der Serie Ajax in Action habe ich verschiedene Lösungsalternativen für module Ansätze mit Spring MVC beschrieben und die Lösung favorisiert, die mittels AJAX a la DWR GUI-Komponenten nachlädt.

In diesem Artikel wird Lösungsalternative 3 genauer beschrieben und kritisch hinterfragt.

Wir möchten folgende GUI Komponente per DWR an den Server schicken:

Artikelnummer: 12-38872662

Artikelbeschreibung, Grösse, Farbe, Preis. etc.




Anschliessend soll sich der Warenkorb im GUI neu auszeichnen und den/die neuen Artikel anzeigen, alles ohne POSTBACK. Wir brauchen also einen DWR Bean, was den ASYNC Call abarbeitet: CartManagerAdapter.

public class CartManagerAdapter {
public void addItemToCart(String pk, int quantity) {
// call service to add the item
}
}

Und eine Spring-enabled DWR Konfiguration hierzu:

<dwr>
<allow>
<create creator="spring" javascript="cartManager">
<param name="beanName" value="cartManagerAdapter" />
</create>
</allow>
</dwr>

Dazu hängen wir eine eine JavaScript Methode an den submit Event:

<input type="button" name="submit" value='add to cart' onclick="addItemToCart()" />

und definieren folgende JS Funktionen:

<script type="text/javascript">
function addItemToCart() {
document.getElementById('loadingMsg').style.display = 'block';
var id = dwr.util.getValue("id");
var q = dwr.util.getValue("quantity");
cartManager.addItemToCart(id,q,addItemToCartCallback);
return;
}

var addItemToCartCallback = function() {
getCart();
document.getElementById('loadingMsg').style.display = 'none';
}
</script>

Damit unser Warenkorb sich nach dem callback neu auszeichnet, rufen wir getCart() auf um folgendes zu tun:

function getCart() {
cartManager.getCart(getCartCallback);
return;
}

var getCartCallback = function(cartBean) {
var text = '<ul>';
for(i = 0; i < cartBean.cartBeanEntries.length; i++) {
text += '<li>';
text += cartBean.cartBeanEntries[i].quantity;
text += 'x ';
text += cartBean.cartBeanEntries[i].name;
text += '</li>';
}
text += '</ul>';
document.getElementById('cart').innerHTML = text;
}

Die CartManagerAdatper Klasse wurde dafür um die Methode getCart() erweitert:

public class CartManagerAdapter {
...
public CartBean getCart() {
return getCartService().getCart();
}
}

Wenn man diesen Prototyp nun kritisch hinterfragt kommt man zu folgenden Punkten:

  • Man umgeht Spring MVC durch den Einsatz von DWR

  • Es gibt kein Binding + Validation durch Spring -> man muss das selbst veranlassen

  • Viel JS Scripting

  • Validation und sonstiges Error-Handling muss gescripted werden

  • Serverseitige Zustandsinformationen müssen bei jedem Roundtrip über die AJAX Engine geliefert werden, z.B. authentiated principal

  • MVC besteht nicht mehr - Paradigmawechsel!


Man muss ich sich sehr gut überlegen, wo und in welchem Umfang man AJAX einsetzen möchte. In diesem Prototyp kommen wir zur Erkenntnis, dass man MVC aushebelt und damit Kernfunktionen, die Spring MVC mitbringt nicht nutzen kann, d.h. man muss diese selbst implementieren. Am Ende baut man viel um Infrastukturprobleme zu lösen, nicht aber das Business Problem.

Trotzdem soll der Prototyp weiter untersucht werden, denn es ist noch nicht klar, wie ein Exception Handling abgebildet werden soll. Dazu mehr im kommenden Post.

Keine Kommentare: