JUrfa Java için çok basit ve tüy-siklet MVC kütüphanesidir. Annotation'lar yardımıyla kontrol, değer yükleme ve basit validasyonlar sağlar. Google App Engine için tasarlanmıştır. Ancak basit yapısından dolayı her türlü web uygulamasında kullanılabilir.
Struts, Spring günümüzde Java dünyasında sıklıkla kullanılan framework'ler. İkisi de birbirinden güzel. Lakin GAE (Google App Engine) üzerinde proje geliştirirken ikisinde de problem yaşadım. GAE üzerindeki JVM'de bir whitelist var ve bunun dışındaki sınıfları kullanamıyorsunuz. Struts ve Spring de çok kapsamlı framework'ler olduğu için illaki bu whitelist'e takılıyor. (Struts hiç çalışmıyor, Spring MVC bir yere kadar çalışıyor)
Jsp-Servlet ile proje geliştirmek de çok zayıf olduğu için illaki bir framework'den yararlanmak gerekiyor. Struts ve Spring gibi büyük framework'ler öğrenmek zaman alıyor, aynı zamanda sürekli yeniliklerin takip edilmesi gerekiyor. Oysa ki web demek http protokolü demek ve bu protokol seneler içinde çok da değişmedi :)
Framework'ümüzün isminin JUrfa olmasının sebebi, acısız olması. Yani diğer MVC framework'lerini öğrenip, ayağa kaldırırken çektiğimiz acıların bunda bulunmaması, acısız mvc framework'ü olması :)
Java ile web uygulaması geliştiren veya geliştirmek isteyen herkes, Java ile GAE uygulaması geliştirmek isteyenler için birebirdir. Hep varolanı kullanmak yerine gerçekten teknoloji üretmek isteyenler de kullanıp yorumlarını esirgemezler ise tadından yenmez.
Filter olarak web.xml'e tanımlayacağımız JUrfaFilter tüm istekleri dinleyip @ActionHandler ile belirttiğiniz path'e uygun bir istek bulursa (regular expression'da kullanılabiliyor) bu isteği sizin Action nesnesinden türettiğiniz sınıfa gönderiyor. Bunun haricinde eğer get ya da post metodu ile gönderilen bir parametre var ise bunu o sınıfa tanıttığınız değişkene @ActionParam ile de tipine göre cast ederke map'leyebiliyor. Aynı zamanda basit validasyonlar yapma yeteneği de var. Bunun sonucunda belirtiğiniz success view'ına ya da Exception durumunda fail view'ına yönlendirme yapıyor.
Böylece tek tek servlet yazıp, web.xml'e müdahale etmek zorunda kalmıyorsunuz, aynı zamanda get ya da post metoduyla gelen parametreleri değişkenlere atıp null kontrolü gibi basit validasyonlardan kurtuluyorsunuz. Ekstradan herhangi bir library kullanmadan url rewrite yapabiliyorsunuz Bütün bunlar için sadece 20KB'lık bir jurfa.jar'ı projenize eklemek yetiyor.
Bana hakanilter@jurfa.com üzerinden erişebilirsiniz. Her türlü yorum, eleştiri ve yardıma açığım, beklerim :)
JUrfa web projesine çok basit bir şekilde adapte edilebilir. Öncelikle bir web projesi açıp jurfa-mvc-x.x.x.jar dosyasını ekliyoruz.
Daha sonra web.xml dosyasına aşağıdaki satırları ekleyerek JUrfa'nın filter sınıfını tanıtıyoruz. Buradaki parametrelerden actionBase, Action sınıflarının hangi paket altında olacağı. Sizin projenizde Action sınıfları hangi paketin altında olacaksa buraya onu yazmanız gerekiyor.
Bundan sonra normal bir sınıfı Action sınıfına dönüştüreceğiz. bizim projemizde actionlar com.itstanbul.sample.action paketinin altında olacak
LoginAction ismini verdiğimiz sınıfı Action sınıfından türetiyoruz, bu sınıf bize Servlet'lerden tanıdığımız doGet ve doPost metodlarını override edebilmeyi sağlıyor. Bundan sonra da Action sınıfımızın tepesine @ActionHandler annotation'ı koyarak controller özelliği veriyoruz. Burada path="/login" değeri uygulamamızda /login kaynağı çağırıldığı zaman isteğin bu sınıfa geleceğini belirtiyor. success="success.jsp" ile sınıf içerisinde herhangi bir hata olmadığı durumda yöneleneceği view belirtiliyor. Aynı şekilde sınıfın çalışması esnasında bir exception oluşursa fail ile belirtilen view'a yönleniyor.
Sınıfımız login işlemi yapacağı için user ve pass isimli iki değişken tanımlıyoruz. Bu değişkenlerin html tarafındaki form elementineden gerekli değerleri otomatik olarak alması için tepelerine @ActionParam annotation'ı yerleştiriyoruz. Bu annotation hem request scope'undaki değerleri sınıfın içindeki değişkenlere map ediyor, hem de basit validation yapmamızı sağlıyor. Burada required=true diyerek bu değerlerin mutlaka doldurulması gerektiğini belirtiyoruz. Bu değerler doldurulmaz ise ValidationException oluşuyor.
Biz bu örnekte post metodunu kullanıyoruz, required=true dediğimiz için doPost metodunda null kontrolü bile yapmamıza gerek yok. doPost metodunda gerekli kodumuzu yazıp devam ediyoruz. Burada JUrfa'nın setParameter() metodu ile durum ile ilişkin bilgiyi model nesnemize giriyoruz. Bu veriyi önyüzde kullanacağız.
JUrfa mvc "basit iyidir" mantığında olduğu için,JSTL kullanımını tavsiye ediyor. Bunun için jstl-1.2.jar dosyasını da projeye ekliyoruz. Daha sonra index.jsp dosyasını hazırlıyoruz. Burada /login'e post metodu ile u ve p input'larını gönderiyor olacağız.
Başarılı olma durumunda yönlenilecek success.jsp dosyasını hazırlıyoruz. Action sonunda oluşacak mesajı ile ekrana basacağız.
Aynı şekilde fail.jsp dosyasını hazırlıyoruz.
Uygulamayı çalıştırıyoruz. index.jsp dosyasında user ve pass bilgilerini giriyoruz.
Aksiyon sonucunu görüyoruz.
Afiyet olsun...
JUrfa'nın çalışabilmesi için web.xml dosyasına aşağıdaki gibi filter tanımlanması yapmak gerekir.
jurfa com.jurfa.filter.JUrfaFilter actionBase com.itstanbul.sample.action encoding UTF-8 jurfa /*
@ActionHanler annotation'ı aşağıdaki değerleri alır:
@ActionHandler(path="/login", success="success.jsp", fail="fail.jsp", contentType="text/html" redirect=RedirectMethod.FORWARD, cacheTimeout=-1)
path: Action'ın hangi isteğe cevap vereceği. Örneğe göre /login isteği gelirse bu sınıf tetiklenir.
pattern: Eğer aksiyon örtüşmesini regular expression kullanarak yapmak istiyorsanız o zaman bu alana ilgili pattern'i yazıp, path özelliğine de ActionHandler.PATTERN değerini vermek gerekiyor. Bunun örneğini ayrıca eklenecek.
success: Action başarılı bir şekilde sonlandığı zaman hangi view'a gidecek. Zorunlu alan değildir. Action içerisinde istenilen şekilde yönlendirme de yapılabilir. Bu örnekte success.jsp'ye yönlenir.
fail: Action işletilirken exception oluşursa ve fail alanında bir view belirtilmiş ise oraya yönlenir. Eğer tanımlı değilse exception throw edilir. Burada fail.jsp'ye yönlenir.
contentType: Aksiyon sonucundaki çıktının content-type'ı burada belirtilebilir. Zorunlu değildir ve varsayılan değeri "text/html"'dir.
redirect: Aksiyon işletildikten sonra yönleneceği bir view tanımlı ise, bu view'a hangi şekilde yönleneceği buradan belirtilebilir. Bu değerler RedirectMetod enum'ında tanımlanmıştır. FORWARD, REDIRECT ve INCLUDE olabilir. Zorunlu değildir ve varsayılan değeri "FORWARD"'dır.
cacheTimeout: Varsayılan olarak -1 yani no-cache durumundadır. Buraya belirtilen değer dakika cinsinden Action metodunun işletilmesi sonucu model nesnesine eklenen değerlerin memory üzerinde cache'lenmesini sağlar. Yani output'u değil Action metodunun sonucunda doldurulan model nesnesini belirtilen süre kadar dakika yeniden çalıştırmaz, cache'den getirir. Çok kullanışlı bir özellik değil, kompleks bir cache mekanizması sunmaz. Experimental bir özelliktir.
@ActionParam annotation'ı, view'dan gelen request scope'undaki değerleri sınıfın içerisindeki değişkenlere atmak ve validation yapmak amacında kullanılır. Örnek kullanım ve parametreleri:
@ActionParam(name="user", min=3, max=10, required=true, error="Geçerli bir kullanıcı adı giriniz.") private String userName;
name: Request scope'unda olan değişkenin adıdır. Zorunlu değildir, belirtilmediğinde değişkenin adıyla aynı olması gerekir. Örnekte html tarafından user isimli değişkenin değeri Action tarafında userName'e değer olarak aktarılır.
min: Parametre sayısal ise, minimum alacağı değeri belirtir. Bu değerden düşük bir değer varsa ValidationException fırlatılır. Eğer parametre sayısal değil de String ise, o zaman en az min değeri kadar karakter içermesi gerekir. Örneğe göre userName değişkeni en az 3 karakter olmalıdır.
max: Parametre sayısal ise, maksimum alacağı değeri belirtir. Bu değerden büyük bir değer varsa ValidationException fırlatılır. Eğer parametere sayısal değil de String ise, o zaman en fazla max değeri kadar karakter içermesi gerekir. Örneğe göre userName değişkeni en fazla 10 karakter olabilir.
required: required=true olarak belirtildiğinde bu değişkenin değeri null olamaz.
error: Zorunlu alan değildir. Belirtildiği durumlarda validasyon hatası oluşursa model nesnesine "validationError" değişkeni olarak burada belirtilen değeri verir. Böylece view tarafında kullanıcıya oluşan durumla ilgili bilgi verilebilir. Jstl kullanılıyor ise $model.validationError gibi.
@UrlParam annotation'ı, Action'a ait path'den veri almak için kullanılır.
@UrlParam(index=1, min=3, max=10, required=true, error="Geçerli bir kullanıcı adı giriniz.") private String userName;
index: index bilgisi 0'dan başlayarak url'nin / ile ayrılan parametrelerinin indexidir. (Örnek: /customers/customer/haqen gibi bir url de index=0 değeri customers olur)
Diğer özellikleri ActionParam ile aynıdır.
Derlenmiş kodlara buradan erişebilirsiniz.
Kaynak kodlar için SVN üzerinden şöyle erişebilirsiniz:
svn checkout http://jurfa.googlecode.com/svn/trunk/ jurfa-read-only
Google Code proje sayfasına http://code.google.com/p/jurfa/ üzerinden erişebilirsiniz.