Thursday 26 July 2007

JSF - URL'den bean metoduna erişim & Shale Remoting

Geçenlerde, database'de tutulan ve sürekli değişen bir listenin uygulamamız içinden ulaşılabilmesi için bir proje yapayım dedim. Yeni bir proje yapıyorum madem, farklı teknolojiler kullanayım istedim ve jsf - hibernate kullanarak bir proje hazırladım. Proje tam isteğime karşılık veren basit bir proje oldu. Tek form alanı olan ve üç butonu olan basit bir arayüzden id kullanarak database'den sorgulama yapıyordum, basit bir de validasyon ekledim. Pembe pancurlu şirin bir uygulama oldu.

Benim için asıl önemli olan kısma yani uygulama içinden bu jsf projesine link vermeye geldi. Malesef, benim backing bean'in bir metodunu çağırmam ve bu metoda parametre olarak database'deki kaydın id'sini geçirmem gerekiyordu. Struts'ta her zaman yaptığımız şey canım, ne olacak, url'den veririm parametreleri, bean'de de ilgili metodda alır kullanırım düşüncesindeydim. Namümkün. En azından o kadar kolay olmadı.

JSF'e verilecek URL'ler navigation-url'lerle tanımlanan view-id'lere veriliyor. Backing bean'e ulaşmak için benim jsp üzerinden gitmem gerekiyordu. JSF, bütün bir lifecycle tamamlanmadan önce, kullanıcı session'ında bir view'un hazır olmasını şart koşuyor anladığım kadarıyla.

Çok genel olan bu gereksinimi araştırdım ve birkaç yönteme ulaştım:

- Yine jsp'ye gidilir ve request parametresi şu şekilde okunur ilgili form alanı içine: #{facesContext.externalContext.requestParameterMap.paramismi} ardından jsp üzerinden bean'e ulaşılır.
- Apache shale remoting kullanarak short circuit yapıp jsf framework akışının arasına girilir (kulağa hoş geliyor)
- Custom servlet kullanılarak requestin önce bu servlet'e gelmesini, ardından da bir faces UIViewRoot oluşturup response'un oraya yönlenmesi sağlanır.

Shale remoting'i denemeye karar verdim. Shale 1.0.4 kullandım bunun için.

Adımlar şöyle:
Öncelikle şu library'leri ekledim projeme.
shale-core-1.0.4.jar
shale-remoting-1.0.4.jar


web.xml'imde şunların olması gerekiyor.

<context-param>
<param-name>
org.apache.shale.remoting.CLASS_RESOURCES
</param-name>
<param-value>
/static/*:org.apache.shale.remoting.impl.ClassResourceProcessor
</param-value>
</context-param>

<context-param>
<param-name>
org.apache.shale.remoting.DYNAMIC_RESOURCES
</param-name>
<param-value>
/dynamic/*:org.apache.shale.remoting.impl.MethodBindingProcessor
</param-value>
</context-param>

<context-param>
<param-name>
org.apache.shale.remoting.WEBAPP_RESOURCES
</param-name>
<param-value>
/webapp/*:org.apache.shale.remoting.impl.WebResourceProcessor
</param-value>
</context-param>



Böylece, bean metodları gibi dinamik kaynaklara ulaşmak için kullanacağım "dynamic" context parametresi yanında, uygulama içindeki css, js vb. dosyalara ulaşmak için kullanabileceğim "static" context parametresi de tanımlanmış oldu.

Bean'de çağrılmasını istediğim metodun başına şu kısmı da ekledim. Böylece url sonunda GET ile gelen refcode adlı parametreyi alabileceğim.

FacesContext context = FacesContext.getCurrentInstance();

String refCode = (String)context.getExternalContext().getRequestParameterMap().get("refcode");

faces-config'imin içinde ilgili bean'in ismi innerForm ve çağıracağım metodun ismi de queryByURL. Denemek için çağıracağım URL de şu:

http://server_ip:port/Module_name/dynamic/innerForm/queryByURL.faces?refcode=440331

Bean'e başarıyla ulaşıp işlemlerimi yapabiliyorum fakat tekrar jsf framework akışına dönmek istediğimde yani metodun işi bittikten sonra faces-config'de tanımlı bir navigation-rule'a dönmek istediğimde hata alıyorum. Üzerinde çalışıyorum. Artık kısmet ...

5 comments:

faruk said...

merhabalar,
bende aynı sorunla bu aralar ugrasyorum geçen zaman içine bir çozume ulaştınızmı acaba ?

struts için çok basit olan bu durum malesef jsf te çok zor !! mu oluyor?

sadece gerekli olan bi url action olarak kullanılabilr mi ?

Mahir Tarlan said...

Malesef o zamandan beri bakamadım. JSF'te bunca zahmete gireceğime action based bir mvc kullanırım daha iyi diye düşündüm.

Ama ilk fırsatta tekrar inceleyeceğim. Bir sonuca varırsam buradan paylaşırım tekrar :)

enes said...
This comment has been removed by the author.
enes said...

FacesContext.getCurrentInstance().getExternalContext().
getRequestParameterMap().get(paramname);

seklinde Bean icinde request parametresini alin. bunu jsf backing beanindeki ilgili metoda yerlestirirseniz zaten jsf uzantisiyla bu url bu metoda ulasacak ve parametreyi alacaksiniz.

www.enesakar.com
www.dikeyarama.com

Unknown said...

FacesContext.getCurrentInstance().getExternalContext().
getRequestParameterMap().get(paramname);

teşekkürler enes, işe yarıyor...