Friday, September 17, 2004

Struts: Menghindari error kehilangan list ketika validasi gagal (prepopulation problem)

Seringkali kita membuat object List atau Collection dari data yang tersimpan di database untuk dropdown-list (combo box) pada halaman html dengan cara memanggil method pada business layer. Pemanggilan method yang menghasilkan List tersebut dilakukan oleh struts Action kemudian disimpan pada scope request.
public ActionForward execute(ActionMapping mapping, ... ) {


List currencyList = CurrencyService.getAllCurrency();
request.setAttribute("currencyList ", currencyList);
...

}
Dihalaman jsp kemudian kita membuat script seperti ini:
  <html:select property="currencyId">

<html:options collection="currencyList" property="lookupId" labelproperty="codeAndDescription"/>
</html:select>
Menyimpan list di scope request saat eksekusi Action akan menjadi masalah jika validasi pada struts form-bean menghasilkan error dan input mapping adalah halaman jsp yang sama dimana diperlukan list untuk dropdown combo. Masalahnya adalah list tidak tersedia di scope request karena setelah validasi mengghasilkan error, Action tidak dieksekusi.

Solusi yang biasa saya lakukan adalah dengan meyimpan list di scope request jika method validate() di form-bean menghasilkan error selain juga di Action.
public ActionErrors validate(ActionMapping map, HttpServletRequest req) {

ActionErrors errors = new ActionErrors();
...
if (!errors.empty()) {
//
List currencyList = CurrencyService.getAllCurrency();
request.setAttribute("currencyList ", currencyList);
}
}
Tentu saja ini kurang baik, karena adanya duplikasi code di form-bean dan di Action. Cara lain yang lebih baik adalah meyimpannya di method reset() pada form-bean sehingga tidak terjadi lagi duplikasi, karena method reset() akan dipanggil setiap kali sebelum form dibuat. Cara kedua ini kurang elegan karena melakukan pemanggilan proses bisnis pada form-bean yang menyulitkan maintenance.

Agar lebih baik, buatlah sebuah class facade dengan method-method static untuk melakukan hal tersebut:
public void reset(ActionMapping arg0, HttpServletRequest request) {

LookupUtility.setCurrencyList(request);
...
}
...akhirnya, saya menemukan artikel terkait dengan tulisan ini (ide tulisan ini sudah ada sebelum artikel dibawah ini ditulis, agak aneh kenapa masalah yang biasa terjadi tidak banyak ditulis orang padahal artikel struts begitu banyak di internet):

How to make sure request scoped lists persist when validation fails

Tulisan lain yang membahas masalah ini: Prepopulation - the three action edit

No comments:

Followers