spring mvc uygulama catisi osunercan wwwjavadilicom

32
Spring MVC Uygulama Çatısı Ömer SUNERCAN [email protected] 2006, Ankara

Upload: wwwjavadilicom

Post on 09-Jun-2015

1.394 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

Spring MVC Uygulama Çatısı

Ömer [email protected]

2006, Ankara

Page 2: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

İçindekilerGiriş......................................................................................................................................................3

Belge İçeriği Hakkında....................................................................................................................3Spring MVC..........................................................................................................................................3

Geliştirme Ortamının Hazırlanması.................................................................................................3Kurulum......................................................................................................................................3Uygulama Kılavuz Yapısının Oluşturulması...............................................................................4

Başlangıç (DispatcherServlet).........................................................................................................4İlk Spring MVC Örneği...................................................................................................................5Uygulamaya Başlıyoruz.................................................................................................................11Ana Sayfa.......................................................................................................................................13Form Kullanımı..............................................................................................................................15Araç Girişi......................................................................................................................................17Doğrulama (Validation).................................................................................................................23Durdurucular (Interceptors)...........................................................................................................28

Sonuç..................................................................................................................................................31Terimler Sözlüğü................................................................................................................................32Kaynaklar............................................................................................................................................32

Page 3: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

GirişSpring, son dönemde J2EE uygulaması geliştirme alanında popülerlik kazanan ve yaygın olarak kullanılmaya başlanılan bir uygulama geliştirme çatısıdır (application framework). Uygulama geliştirmeyi ve denetimi zorlaştıran ağır  (heavy­weight) çözümlere alternatif olarak hafif (lightweight) bir yapı sunarken, aynı zamanda esnek ve modüler bir şekilde bir çok özelliği içerisinde barındırması Spring'e gösterilen ilgide önemli rol oynar.

Spring, birbirinden bağımsız ve ihtiyaca göre kullanımına karar verilebilecek bir çok farklı özellik içerir. Bu özellikler çatıyı oluşturan yedi farklı birim tarafından sağlanır. Bu belge bunlardan Web MVC (Model View Controller / Model Görüntüm Denetim)  biriminin kullanımını  örneklemek amacı  ile  hazırlanmış  olduğu  için bu birimlerin  tek  tek ele alınmasına yer verilmeyecektir.

Spring temel olarak, bileşenleri  XML yapılandırma kütükleri  aracılığıyla bütünleştirmeye dayalı  bir  yapı sunar.  Bu yaklaşım esas olarak Denetim Çevrimi (Inversion of Control), diğer bir adıyla Bağımlılık İletimi (Dependency Injection), tasarım   örüntüsünü   kullanır.   Buna   göre,   bileşenler   arasındaki   bağımlılıklar   bileşenlerin   kendileri   yerine   Spring tarafından ele alınır. 

Spring bileşenleri bir araya getirmek ve biçimlendirmek için Java çekirdeklerini (JavaBean) kullanır. Sınıfları kodlanan bu   çekirdeklere   dair     isimlendirmelerin   yapılması,   gerekli   ilk   değer   atamaları   ve   diğer   çekirdeklerle   aralarındaki bağımlılıkların tanımlanması XML yapılandırma kütüklerinin içerisinde yapılır. Spring, bu kütükleri okur ve buradaki tanımları   kullanarak   çekirdek   olgularını   gerekli   yapılandırmaları   gerçekleştirerek   oluşturur.   Bu   işleyiş   sayesinde uygulamadaki bileşenlerin yapılandırılması ve kullanımı kodun içine girmeye gerek kalmadan, yapılandırma kütükleri aracılığıyla son derece esnek ve kolay bir biçimde gerçekleştirilir. İleride ele alacağımız Web MVC birimi örneklerinde bunu çok daha somut şekilde görme ve inceleme olanağı bulacağız.   

Belge İçeriği Hakkında...Bu belgede yoğun bir şekilde bilgiye yer vermek yerine, Spring MVC ile başlangıç düzeyinde basit bir uygulamanın geliştirilmesi örneklenmeye çalışılacaktır. Özellikle başlangıç aşamasında kavranılmakta zorlanılabilen kavramlara ve geliştirme sürecinde ortaya çıkabilen temel sorunlara yönelik çözümlere yer verilecektir.   

Bu belgede anlatılanların iyi kavranılabilmesi için temel J2EE bilgisine (JSP/Servlet, JSTL, JSP EL) yeteri kadar sahip olunması gerekmektedir. Spring MVC çatısının kullanımı tamamen giriş düzeyinde ele alınmış olup, bazı noktalarda atıflar bulunsa da okuyucunun Struts vb. bir çatıyı daha önce kullanmış veya biliyor olması gereksinimi yoktur.

Belge içinde verilecek olan kodların tamamı çalıştırılarak denenmiş  kodlar olmalarının yanısıra, okuyucuya kolaylık olması   amacıyla,   tekrar   tekrar   verilen   kaynak   (java)   ve   yapılandırma   (xml)   kütüklerinin   içieriklerinin   sadece güncellenen kısımları değil, her her seferinde tamamı verilecektir.   

Son olarak, MVC'nin Spring'in bir alt bölümü olduğundan hareketle metnin içerisinde bir çok yerde Spring MVC yerine sadece  Spring  ifadesine yer verilecektir, bunun bir kavram kargaşasına yer açmaması için hatırda tutulmasında fayda vardır.

Spring MVCBu bölümde Spring MVC çatısının kullanımını baştan sona adım adım ilerleyerek geliştireceğimiz bir uygulama ile örnekleyeceğiz.

Geliştirme Ortamının Hazırlanması

KurulumÖrnek uygulamamızı gerçekleştirmeye uygun bir çalışma ortamı hazırlayarak başlayacağız. 

Spring MVC ile bir J2EE uygulaması geliştirmeye başlamak için öncelikli ihtiyaçlarımız bir Java SDK'sı ve bir Servlet Kozası  (Servlet  Container)  'dır.  Örnek uygulamamız jdk1.5.0 Java SDK'sı  ve koza olarak da Apache Tomcat 5.5.9 üzerinde çalışacaktır.

Kullanılabilecek   değişik   araçlardan   bağımsız   olması   için   derleme,   yükleme   vb.   amacıyla   herhangi   bir   araç kullanmayacağız. Siz isteğinize bağlı olarak Ant gibi bir araç veya seçtiğiniz bir IDE kullanarak bu işlemleri alışagelmiş olduğunuz bir şekilde gerçekleştirebilirsiniz. Bu nedenle bu işlemlere dair ayrıntılara yer verilmeyecektir. 

Page 4: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

Yukarıdaki   kısım   herhangi   bir   J2EE   uygulaması   için   gerekli   olan   ortama   ilişkin   ihtiyaçlardı.   Spring   MVC'yi kullanabilmek   için  www.springframework.org/download.html  adresinden   Spring   çatısını   indirmeniz   gerekmektedir. Burada karşınıza iki seçenek çıkacaktır:

spring­framework­<sürüm_no>.zip

spring­framework­<sürüm_no>­with­dependencies.zip

İlk seçenek sadece Spring çatısını içerirken, ikinci seçenekle birlikte J2EE uygulaması geliştirmek için gereken diğer bir çok arşiv de gelir.  Uygulamamızda spring­framework­1.2.5­with­dependencies.zip kurulumu kullanılacak.

Spring çatısını   indirdikten sonra  istediğiniz  bir  yere açtığınızda kurulum tamamlanmıştır.  Uygulamamızı geliştirme aşamasında gerektikçe buradan Spring MVC çatısına ilişkin arşivleri uygulamamızın içine dahil edeceğiz. 

Uygulama Kılavuz Yapısının OluşturulmasıUygulamamızı  geliştirmeye gerekli  kılavuzları  oluşturarak başlayabiliriz.  Uygulamamızın adı  springornek  olsun, bu durumda uygulamamız için kök kılavuzun adı da  springornek olmalıdır. Öncelikle bir J2EE uygulaması için standart olan WEB­INF kılavuzunu ve web.xml kütüğünü oluşturmamız gereklidir.

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"> </web-app>

Kod 2.1 springornek/WEB-INF/web.xml

J2EE standardı olarak sınıflar için  classes kılavuzunu ve ekleyeceğimiz kütüphaneler için  lib kılavuzunu oluşturalım. Biz Java kaynak kodlarını koymak üzere WEB­INF'in altında bir  src  kılavuzu öngörüyoruz, siz kullanacağınız araca veya isteğinize göre size uygun seçimi tercih edebilirsiniz. Son olarak JSP sayfalarımızı koymak için  WEB­INF/jsp kılavuzunu oluşturalım. Bu şekilde JSP sayfaları dışarıdan doğrudan erişime kapatılır ve uygulamadan fiziksel olarak sistemde bulunmayan sayfalara işaret eden adreslerin (url) yönlendirilmesi yoluyla sistemden hizmet alınabilir. 

Gördüğünüz   gibi   Spring   çatısını   kullanmak   için   herhangi   bir   uygulamadan   farklı   bir   yapıya   ihtiyaç   duyulmuyor. Spring'in aktif olarak kullanımı için yapılması gereken tek şey ileride açıklayacağımız üzere gerekli jar arşivlerini  lib kılavuzunun içerisine koymak ve XML yapılandırma kütüklerinin içeriğini düzenlemek olacak.

Başlangıç (DispatcherServlet)Spring   MVC,   Spring   çatısı   içerisinde  MVC  (Model   View   Controller   /   Model   Görünüm   Denetim)  mimarisinin gerçekleştirildiği  birimdir.  Bilindiği  gibi  MVC bir uygulamada kullanıcıya sunulan görüntü  (view),  veri  (model)  ve kullanıcıdan gelen taleplere karşılık olarak veriler üzerinde işlemleri gerçekleştiren denetim  (controller)  bölümlerini birbirinden ayırmayı öngören bir yaklaşımdır. Bu yaklaşımın J2EE uygulamalarındaki esaslarından birisi Ön Denetimci  Servlet (Front Controller Servlet)'in gelen tüm HTTP isteklerini (request) karşılaması ve bu isteği tanımlanan eşlemelere (mapping) göre değerlendirip yanıtı (response) üretecek olan işleyicilere (handler) yönlendirmesidir.  

Spring MVC'de Ön Denetimci (Front Controller) Servlet olarak DispatcherServlet hizmet verir. Spring MVC'de işleyicilere karşılık olarak da Controller arayüzünü (interface) uygulayan (implement) sınıflardır. 

Artık Spring MVC'yi uygulamamızın içine dahil etmenin zamanı geldi. Bunun için öncelikle Spring kurulumunuzun içindeki spring.jar (spring­framework­1.2.5/dist/spring.jar) arşiv kütüğünü WEB­INF/lib kılavuzunun içine kopyalayın. 

Spring kütüphanesini uygulamaya dahil ettiğimize göre artık Spring'e özel işlemler yapmaya başlayabiliriz. Yukarıda Spring'de  Ön Denetimci  olarak  DispatcherServlet  Servlet'inin işlev gördüğünden söz etmiştik. Bu nedenle ilk adım olarak uygulamaya gelen tüm istekleri bu Servlet'e yönlendirmeli ve böylece uygulamanın denetimini tamamen Spring'e bırakmalıyız. Bunu gerçekleştirebilmek için  web.xml kütüğüne bir Servlet tanımı eklememiz gerekiyor (Kod 2.2).

Görüldüğü üzere uygulamamızın adı olan  springornek  adı ile bir Servlet tanımı ekliyoruz ve Servlet sınıfı olarak da DispatcherServlet'i belirtiyoruz. Ayrıca  htm  ile sonlanan tüm url'lerin bu Servlet'e yönlendirilmesi gerektiğini belirtiyoruz. Buna göre bu uygulamaya gelen (<sunucu>/springornek ile başlayan) ve htm ile sona eren url'ler Spring'in DispatcherServlet'i tarafından değerlendirilecek ve buna isteğe buna göre cevap verilecektir. 

Page 5: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.4"> <servlet> <servlet-name>springornek</servlet-name>

<servlet-class> org.springframework.web.servlet.DispatcherServlet

</servlet-class>        <load-on-startup>1</load-on-startup>

</servlet><servlet-mapping>

<servlet-name>springornek</servlet-name> <url-pattern>*.htm</url-pattern>

</servlet-mapping></web-app>

Kod 2.2 springornek/WEB-INF/web.xml

Yeri   gelmişken  DispatcherServlet'in   davranışını   belirleyen   tanım   ve   yapılandırılmaların   bulunduğu   XML yapılandırma kütüğüne değinelim. Spring MVC çatısı bu yapılandırma kütüğü için

<uygulama_adı>­servlet.xml

şeklinde   bir   adlandırma   öngörmüştür.   Bu   durumda   bizim   yapılandırma   kütüğümüzün   adı  springornek­servlet.xml olmalıdır ve bu kütüğün springornek/WEB­INF/ kılavuzunun altında bulunması gerekmektedir. Bu kütüğün henüz hiç bir tanım yapılmamış haldeyken görünümü Kod 2.3'de veriliyor. 

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans></beans>

Kod 2.3 springornek/WEB-INF/springornek-servlet.xml

İleride gerekli tüm tanımlamaları beans etiketleri arasına ekleyeceğimiz bean etiketleri ile bu kütükte yapacağız.

İlk Spring MVC ÖrneğiSpring MVC kullanarak hazırlayacağımız bir sayfa için temel olarak iki kütüğe ihtiyacımız vardır. Bir görünüm (view) ve bir denetimci  (controller). Spring MVC birden fazla görünüm teknolojisine destek vermektedir  (JSP/JSTL, Tiles,  Velocity,  FreeMaker vs.).  Bizim uygulamamızdaki  tüm görünümler JSP (ve JSTL)  ile  oluşturulacaktır.  Bu nedenle görünüm  kelimesinin geçtiği noktalarda bir JSP sayfasından bahsediyor olacağız. 

Denetimciler (controller) daha önce söz edildiği üzere bir HTTP isteğini (request) değerlendiren ve buna göre bir yanıt (response) üretip, bu sonuca uygun bir sayfaya yönlendirme işini yapan sınıflardır. Spring MVC, isteklerin türüne göre en uygun ve en kolay kodlamayı sağlayabilmek için farklı denetim sınıfları içermektedir. Yani örneğin sadece metin ve bir takım bağlantılardan (link) oluşan bir sayfa için farklı, bir submit olayı sonucu üretilen ve form verisi taşıyan bir istek için farklı ve daha uygun bir sınıftan türetilen denetimciler kullanılabilir. 

Denetimci sınıfların en üst düzeydeki atası Controller arayüzüdür. Struts kullanmış olanlar için bunun Action'a karşılık geldiğini söyleyebiliriz.

public interface Controller { ModelAndView handleRequest(

HttpServletRequest request, HttpServletResponse response) throws Exception;

}

Kod 2.4 org.springframework.web.servlet.mvc.Controller

Kod 2.4'te Controller sınıfının koduna yer verilmiştir.  Controller arayüzü  handleRequest()adlı yönetimi 

Page 6: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

sağlar. Bu arayüzü uygulayan sınıflarda bu yöntemin içerisinde istek (request) için yerine getirilmesi gerekenler kodlanır ve   bu   yöntem   geriye   bir  org.springframework.web.servlet.ModelAndView  nesnesi   döndürülür.   Bu nesne sınıf adından da anlaşıldığı gibi yanıt için gerekli olan veriyi (model) de görünümü (view) de taşır. Bunların bir arada   gönderilmesinin   sebebi   kullanıcıya   gösterilecek   görünüme   aynı   zamanda   sunacağı   veriyi   de   sağlanmasıdır. Örneğin bir JSP sayfasının kullanıcının seçimi için listeleyeceği  seçeneklerle ilgili  veriye erişmesi gerekir  (örneğin request  nesnesi  üzerinden).  Bu  nesnenin  (ModelAndView nesnesi)  oluşturulması  ve  kullanımını  uygulamamızın içinde örnekleyeceğiz. 

RequestUtils

org.springframework.web.bind.RequestUtils  sınıfı,  HttpServletRequest    bir   nesnesinin parametrelerine   parametrenin   türünü   belirterek   erişim   sağlayan  static  yöntemler   içerir.   Parametrelere HttpServletRequest  nesnesinin üzerinden doğrudan erişmek yerine bu sınıfı kullanmak tavsiye edilen bir yöntemdir. Örnekler:    String str = RequestUtils.getStringParameter(request, "string_param");    int i = RequestUtils.getIntParameter(request, "int_param", 0);    Integer i = RequestUtils.getIntParameter(request, "integer_param");

Şu ana kadar açıkladıklarımıza dayanarak bir isteğin hangi aşamalardan geçerek bir yanıta dönüştüğünü sıralarsak, istek ilk önce DispatcherServlet tarafından ele alınır, bu Servlet ileride açıklayacağımız eşleme (mapping) yapılandırmasını kullanarak isteği bir denetimciye yönlendirir. Denetimci isteğe dair yapılması gereken işlemleri gerçekleştirdikten sonra bir ModelAndView nesnesi döndürür. Bu nesne hangi hangi sayfanın gösterileceği bilgisinin yanı sıra sunulacak veriye de sahiptir ve bunlardan üretilen bir yanıt (response) kullanıcıya döndürülür.

Denetimciler  ve diğer  ayrıntılara girmeden önce artık “Merhaba Dünya!” mesajını  gösteren bir  ana sayfa yapmaya geçmeliyiz.

Öncelikle sitenin girişi niteliğide olan bir  index.jsp hazırlamalıyız.  Bir J2EE web uygulamasında sitenin açılış sayfası (ana sayfası) web.xml kütüğüne welcome­file etiketi içerisnde verilir ve burada verilen sayfanın açılışta görüntülenmesi için kullanıcıların erişimine açık fiziksel bir kütüğe işaret ediyor olması gerekir. Bu nedenle index.jsp sayfasını WEB­INF/jsp kılavuzuna değil doğrudan uygulamanın kök kılavuzuna koymalıyız (springornek/index.jsp). 

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"> <servlet> <servlet-name>springornek</servlet-name>

<servlet-class> org.springframework.web.servlet.DispatcherServlet

</servlet-class>        <load-on-startup>1</load-on-startup>

</servlet><servlet-mapping>

<servlet-name>springornek</servlet-name> <url-pattern>*.htm</url-pattern>

</servlet-mapping><welcome-file-list>

<welcome-file>index.jsp</welcome-file></welcome-file-list>

</web-app>

Kod 2.5 springornek/WEB-INF/web.xml

Kod 2.5'te görüldüğü gibi web.xml kütüğünü günledikten sonra, Kod 2.6'daki index.jsp sayfasını kaydedip uygulamayı çalıştırdığınızda karşınıza “Merhaba Dünya!” yazan bir sayfa çıkması gerekir.

Ancak daha önce söz ettiğimiz gibi JSP'lerimizin kullanıcıların doğrudan erişimine açık olmasını istemiyoruz ve ana sayfada   da   dahil   tüm   görünümlerin   Spring   tarafından   arka   planda   oluşturulmasını   ve   kullanıcılara   sadece   sanal url'lerden  (.htm   uzantılı)  haberdar   olmasını   istiyoruz.   Ancak   dışarıdan   erişilebilir   bir  index.jsp'den vazgeçemeyeceğimize göre bu durumda çözüm index.jsp'nin hiç bir bilgi ya da görüntü içermeyip, isteği (request) başka bir sayfaya yönlendirmesidir (Kod 2.7).

Page 7: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

<%@ page contentType="text/html; charset=ISO-8859-9" %>

<html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9"> <title>Merhaba Dünya</title></head><body> <h1>Merhaba Dünya!</h1></body></html>

Kod 2.6 springornek/index.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><c:redirect url="/index.htm"/>

Kod 2.7 springornek/index.jsp

Artık  index.jsp  kendisine gelen istekleri  springornek/index.htm  adresine yönlendiriyor. Peki bu adres karşılığında ne yapılacak? Hangi sayfa görüntülenecek? Burada devreye Spring'in sağladığı Görünüm Çözlümleyici (View Resolver) ve İşleyici Eşleme (Handler Mapping) sınıfları giriyor. 

Daha önce denetimci  (Controller)  sınıfların gerekli  işlemleri  yerine getirdikten sonra bir  ModelAndView  nesnesi döndürdüğünden   söz   etmiştik.   Spring'de   görünümler  (view)  biricik   String'ler   ile   ifade   edilebilirler.   Görünüm çözümleyiciler (view resolver) bu String'lere göre doğru görünümleri tespit edip yönlendirmelerin yapılmasını sağlarlar. Daha   önce   söylediğimiz   gibi   Spring   birden   fazla   görünüm  teknolojisini   destekler   ve   bu   nedenle   çeşitli   görünüm çözümleme   sınıfları   sunar.   JSP   teknolojisi   kullanılıyorsa   uygun   olan   görünüm   çözümleme   sınıfı org.springframework.web.servlet.view.UrlBasedViewResolver'dır. Bizim uygulamamızda olduğu gibi   eğer   JSP   ve   JSTL   teknolojileri   bir   arada   kullanılacaksa   en   uygun   çözüm org.springframework.web.servlet.view.InternalResourceViewResolver  sınıfını  kullanmaktır. Görünüm   çözümleyici   sınıfın  DispatcherServlet  tarafından   nesnesinin   oluşturulup   görünüm   çözümlemede kullanılabilmesi   için  springornek­servlet.xml  yapılandırma kütüğüne bu  sınıfa  dair  çekirdek  (bean)  tanımını  ve   ilk değerlerini vermemiz gerekir (Kod 2.8).

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans> <bean id="gorunumCozumleyici" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass"> <value>org.springframework.web.servlet.view.JstlView</value> </property> <property name="prefix"><value>/WEB-INF/jsp/</value></property> <property name="suffix"><value>.jsp</value></property> </bean></beans>

Kod 2.8 springornek/WEB-INF/springornek-servlet.xml

Uygulama başlatıldığında yapılandırma kütüğüne eklediğimiz  bu çekirdeğin  nesnesi  oluşturulur.  Burada  verilen  ilk değerlere göre bir görünümü  (view)   ifade etmek için kullanılan  String'in başına /WEB­INF/jsp/  öneki  (prefix)  ve sonuna .jsp soneki (suffix) getirilerek görünüme dair gerçek adrese ulaşılabilir. Buna göre örneğin bir ModelAndView nesnesi oluştururken belirtilen önek ve sonekleri yazma zahmetine katlanmadan görünüm belirlenebilir. Örneğin /WEB­INF/jsp/hello.jsp görünümüne sadece hello anahtarıyla erişilebilir. Ancak henüz sorduğumuz soruların cevabını bulamadık. Yani  /springornek/index.htm adresinin nereyi gösterdiği kısmı henüz   belirsizliğini   koruyor.   Öncelikle   bu   adrese   karşılık   gelen,   bu   isteği   karşılayan   bir   görünümümüz   ve   bir denetimcimizin bulunması gerekir.  Bu amaçla kısa bir mesaj   içeren küçük bir sayfa yapalım. Bu küçük örnek için doğrudan  Controller  arayüzünü   uygulayan   bir   sınıfımızın   bulunması   yeterli   olacaktır.   Denetimci   sınıflar   için 

Page 8: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

denetim adlı bir paket (package) oluşturalım ve burada ilk denetimcimizi oluşturalım. 

package denetim;

import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.mvc.Controller;

public class BasitDenetimci implements Controller {

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

return new ModelAndView("basit");}

}

Kod 2.9 springornek/WEB-INF/src/denetim/BasitDenetimci.java

Kod 2.9'da verilen BasitDenetimci sınıfı isteği  (request) bir görünüme yönlendirmek dışında bir işlem yapmıyor. ModelAndView  nesnesi oluşturulurken yapılandırıcısına sadece görünüm ismi veriliyor. Daha önce tanımladığımız görünüm   çözümleyici  (view   resolver)  “basit”  adıyla   tanımladığımız   görünüme   karşılık  springornek/WEB­INF/jsp/basit.jsp sayfasını getirecektir ve DispatcherServlet tarafından istek bu sayfaya yönlendirilecektir. Sayfa herhangi   bir   veriye   ihtiyaç   duymayacağı   için  ModelAndView  nesnesi   herhangi   bir   veri  (model)  eklemeden oluşturulup  döndürülmektedir. 

Yazdığımız denetimci sınıfın DispatcherServlet tarafında tanınıp gerekli yönlendirmelerde kullanılabilmesi için onu yapılandırma kütüğüne eklememiz gerekmektedir (Kod 2.10).

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="basitDenetimci" class="denetim.BasitDenetimci"/>

<bean id="gorunumCozumleyici" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass"> <value>org.springframework.web.servlet.view.JstlView</value> </property> <property name="prefix"><value>/WEB-INF/jsp/</value></property> <property name="suffix"><value>.jsp</value></property> </bean>

</beans>

Kod 2.10 springornek/WEB-INF/springornek-servlet.xml

Bu   tanımın   eklenmesiyle   birlikte   uygulama   çalıştırıldığında,  BasitDenetimci  sınıfının   bir   olgusu basitDenetimci  adıyla   Spring   tarafından   oluşturulacaktır.   Bu   nesne   aynı   zamanda   gerektiğinde   (örneğin yönlendirmelerin tanımlanmasında) bu adla çekirdek (bean) diğer tanımlamalarında da kullanılabilecktir. 

Oluşturacağımız sayfanın görünümünü oluşturan basit.jsp Kod 2.11'de verilmiştir. 

Şu   anda   basit   bir   mesaj   sayfasını   görüntülemek   için   gerekli   her   şey   hazır   durumda.   Ancak   tek   eksik DispatcherServlet'in springornek/index.htm adresini BasitDenetimci denetimcisine yönlendirmesi. Bunun için Spring'in daha önce söz konusu ettiğimiz İşleyici Eşleme (Handler Mapping) işlevini kullanmalıyız.

Page 9: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

<%@ page contentType="text/html; charset=ISO-8859-9" %>

<html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9"> <title>springornek</title></head><body> <h1>Hoşgeldiniz!</h1> Örnek Spring MVC uygulaması.</body></html>

Kod 2.11 springornek/WEB-INF/jsp/basit.jsp

Spring  MVC görünüm çözümleme konusunda  olduğu gibi   işleyici   eşleme  konusunda  da  çeşitli   sınıflar   sunar.  Bu sınıfların   çekirdek   tanımlarına   yapılandırma   kütüğünde   yer   verilerek   ve   burada   gerekli   eşleştirmeler   yapılarak uygulamada hangi url'nin hangi  denetimci  tarafından değerlendirileceğini    belirlenir.  Yani bir anlamda uygulamada kullanılan adreslerin   tamamen soyut olması,  başka bir  deyişle   fiziksel  bir kütüğe  işaret  etmesine gerek kalmaması sağlanır. Bu işlevin getirdiği avantajlardan birisi de adresleri belirlemede uzantı vs. kısıtlamalarının bulunmamasıdır. Bizim uygulamamızdaki url'ler  .htm  uzantısı ile sonlanacaktır. Ancak bu bir tercihten öteye geçmemektedir örneğin istenirse hiç bir uzantı da kullanılmayabilir. 

Biz,  uygulamamızda işleyici eşleme amacıyla  org.springframework.web.servlet.handler paketindeki SimpleUrlHandlerMapping  sınıfını   kullanacağız.   Bu   sınıf,   tanımlamalarda   Ant   stili   (örneğin   *,   **   gibi sembollerle toplu olarak eşleştirmelere olanak verir) ifadelere izin veren ve güçlü özellikleri olan bir eşleme sınıfıdır. Başlangıç sayfası olarak yönlendirilen  index.htm  adresinin  BasitDenetimci  tarafından ele alınacağını ifade eden eşlemeyi Kod 2.12'deki gibi tanımlayabiliriz.

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="basitDenetimci" class="denetim.BasitDenetimci"/> <bean id="urlEsleme" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/index.htm">basitDenetimci</prop> </props> </property> </bean> <bean id="gorunumCozumleyici" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass"> <value>org.springframework.web.servlet.view.JstlView</value> </property> <property name="prefix"><value>/WEB-INF/jsp/</value></property> <property name="suffix"><value>.jsp</value></property> </bean>

</beans>

Kod 2.12 springornek/WEB-INF/springornek-servlet.xml

SimpleUrlHandlerMapping türünde urlEsleme adında çekirdek oluşturuluyor. Bu çekirdeğin mappings adlı niteliğinin içine tüm eşlemelere yer verilir. Yeni bir eşleme ekleyeceğimizde  yeni bir  prop  etiketi eklememiz yeterli olacaktır.

Page 10: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

Şu anda çalışabilir  bir  örneği   elde etmiş   surumdayız.  Uygulamanın başlangıç   sayfası  index.jsp,  index.htm  adresine yönlendirme yapar, bu adresin basitDenetimci denetimcisi tarafından ele alınacağına karar verilir, son olarak denetimci basit  görünümüne  (springormek/WEB­INF/jsp/basit.jsp)  yönlendirir ve bu sayfanın içeriğini tarayıcıda Resim 2.1'deli gibi görürüz.

ModelAndView  nesnesinin   veri  (model)  kısmı   bir   harita   mantığı   ile   çalışır.  BasitDenetimci'yi  biraz değiştirerek görünüme bilgi göndermesini sağlayalım (Kod 2.13).

ModelAndView'e   iki   biçimde   veri   ekleyebildiğimizi   görüyoruz.   Bunlardan   ilki  ModelAndView  nesnesinin yapılandırıcısına görünümün ardından anahtar kelime  (bir String)  ve veriyi  (bir Object)  parametre olarak vermektir. İkincisi ise benzer şekilde addObject yöntemini kullanmaktır. Bu yöntem kullanılarak ModelAndView nesnesine istenildiği kadar veri eklenilebilir.  

package denetim;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.mvc.Controller;

public class BasitDenetimci implements Controller {

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

ModelAndView mav = new ModelAndView( "basit", "mesaj", "Bu String türündeki mesaj verisi!");

mav.addObject("birSayi", new Integer(555));mav.addObject("tarih", new Date());return mav;

}}

Kod 2.13 springornek/WEB-INF/src/denetim/BasitDenetimci.java

Resim 2.1 Başlangıç Sayfası

Page 11: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

Bu   durumda   görünümü   de   gönderilen   verileri   görüntülemek   amacıyla   biraz   değiştirmemiz   gerekiyor   (Kod   2.14). Görünüm  içinden   bu   verilere   istek  (request)  nitelikleri   olarak   erişilebilir.   Niteliğe   erişmek  için  ModelAndView nesnesine veriyi koyarken kullandığımız  anahtar kelimeyi kullanabiliriz. Örneklerimizde JSP EL söz dizimini (syntax) kullanacağız ve örneğin “mesaj” anahtar kelimesini kullandığımız  String  türü veriye sayfanın herhangi bir yerinde ${mesaj} şeklinde erişebiliriz. Son değişikliklerden sonra uygulama çalıştırıldığında Resim 2.2'deki görüntü elde edilir.

<%@ page contentType="text/html; charset=ISO-8859-9" %>

<html><head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9"><title>springornek</title>

</head><body>

<h1>Hoşgeldiniz!</h1>Örnek Spring MVC uygulaması.<br><br><br>

<em><strong>Veriler:</strong></em> <br><br>Mesaj: <em>${mesaj}</em> <br>Bir sayı: <em>${birSayi}</em> <br>Tarih: <em>${tarih}</em>

</body></html>

Kod 2.14 springornek/WEB-INF/jsp/basit.jsp

Uygulamaya BaşlıyoruzArtık Spring MVC kullanarak basit web uygulaması geliştirmek için temel altyapımız hazır durumda olduğuna göre kendi uygulamamızı inşa etmeye başlayabiliriz. Bu esnada Spring'in form içeren sayfalarda form verilerinin kontrolünü kolaylaştıran,   kullanıcı   tarafından   girilen   verileri   doğrulama  (validation)  işlemini   uygulama   kodundan   ayıran   ve yalınlaştıran, istek denetimciye ulaşmadan önce ve sonra yapılması gereken işlemlerin gerçekleştirilmesine olanak veren bir yapı (interceptors) sağlayan çeşitli işlevlerini inceleyeceğiz.  Bunlar gibi bir çok işleve değinecek olmamıza rağmen takip etmeyi kolaylaştırmak ve karışıklığa sebep olmamak için olabildiğince az sayıda sayfaya yer vereceğiz.  

Uygulamamız, bir otoparka giriş yapan araçlara otopark gişesinde boş olan bir park yerinin verilmesi (sıradaki yer veya seçilen boş bir yer) ve park yeri verilen aracın plakasının ve park yerinin kaydedilmesi işlemlerini içerecektir. Önce 

Resim 2.2 Denetmicinin Gönderdiği Veriye Erişim

Page 12: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

sayfaları  hazırlarken kullanacağımız,  araçlara ve otoparka  dair  verileri   tutan ve  bunlara  erişim sağlayan  iş  mantığı sınıflarını kodlayarak başlayalım (Kod 2.15, 2.16) ve bu sınıfları ismantigi adlı bir paketin içerisinde toplayalım.

package ismantigi;

public class Arac {

//plaka alanlarıint ilKodu;String harfKodu;int aracNo;

public int getAracNo() {return aracNo;

}public void setAracNo(int aracNo) {

this.aracNo = aracNo;}public String getHarfKodu() {

return harfKodu;}public void setHarfKodu(String harfKodu) {

this.harfKodu = harfKodu;}public int getIlKodu() {

return ilKodu;}public void setIlKodu(int ilKodu) {

this.ilKodu = ilKodu;}

}

Kod 2.15 springornek/WEB-INF/src/ismantigi/Arac.java

package ismantigi;

public class Otopark {

public final static int ARAC_SAYISI = 10;private static Arac[] araclar = new Arac[ARAC_SAYISI];private static int ilkBosYer = 0;

static {for(int i = 0; i < ARAC_SAYISI; ++i)

araclar[i] = null;}

public static void aracParket(Arac arac, int parkYeri) {

araclar[parkYeri] = arac;if(ilkBosYer == parkYeri) {

int gecici = ilkBosYer;do {

ilkBosYer = (ilkBosYer + 1) % ARAC_SAYISI;if(ilkBosYer == gecici) { //Boş yer yok

ilkBosYer = -1;break;

}} while(araclar[ilkBosYer] != null);//dolu Mu?

}}

Page 13: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

public static boolean doluMu(int parkYeri) {return araclar[parkYeri] != null;

}

public static boolean doluMu() {return ilkBosYer == -1;

}

public static Arac[] getAraclar() {return araclar;

}

public static int getIlkBosYer() {return ilkBosYer;

}

}

Kod 2.16 springornek/WEB-INF/src/ismantigi/Otopark.java

Arac sınıfı sadece aracın plakasını tutmaktadır. Plakanın alt alanlarını(il kodu, harf kodu ve araç no) ayrı ayrı tutarak girdi denetiminin daha kolay yapılmasını amaçlıyoruz. Uygulamamızda kaynak kodları karmaşıklaştırıp, şişireceği ve okuyucunun uygulamayı çalıştırmasını zorlaştıracağı  için bir veri tabanı kullanmayacağız.  Otopark  sınıfını bunun boşluğunu doldurabilmek için ekliyoruz. Bu sınıfta park yerlerini ve buralara park eden araçları tutmak için bir Arac dizisi kullanıyoruz ve araçların park yerlerinin dizideki tutuldukları dizinleri olmasını öngörüyoruz. Bu durumda boş olan park yerlerine ilişkin dizinlerin değeri hiç  bir araç  bulunmadığına işaret edecek biçimde  null  olmaktadır. Bu sınıfta  ilkBosYer  adlı   alan   da   anlaşılacağı   üzere   otoparkta   boş   durumda   olan   ilk   noktayı   göstermektedir. Uygulamamızda kullanıcı isterse bundan daha farklı boş bir yeri seçebileceğinden dolayı  aracParket  yönteminin içerisinde bu değişken sadece bir  arttırılmak yerine otoparktaki   ilk  boş  yerin  bulunup bu değerin  atanması   işlemi gerçekleştiriliyor.   Eğer   otoparkta   boş   yer   kalmamışsa   bunu   belirtmek   için  ilkBosYer  değişkeninin   değeri  ­1 yapılıyor.

Ana SayfaUygulamamız için ilk olarak bir  ana sayfa yapalım. Bunu gerçekleştirmek için başlangıç amaçlı yazdığımız denetimci sınıf ve JSP sayfasına benzer şekilde yeni bir denetimci ve  bir JSP sayfası ekleyebiliriz. Ana sayfada hangi park yerinde hangi aracın bulunduğunu  listeleyebiliriz  ve yeni araç  girişinin yapabileceği  sayfaya yönlendiren bir  bağlantıya yer vermemiz gerekir.  Amacımızı gerçekleştirebilmemiz için JSP sayfasının araçlar ve park yerleri bilgisine ihtiyacı vardır, bu nedenle denetimci sınıfın döndürdüğü ModelAndView nesnesinin içine bu bilgiyi eklemesi gerekir (Kod 2.17). 

package denetim;

import ismantigi.Otopark;

import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.mvc.Controller;

public class AnasayfaDenetimci implements Controller {

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

ModelAndView mav = new ModelAndView("anasayfa");mav.addObject("araclar", Otopark.getAraclar());return mav;

}}

Kod 2.17 springornek/WEB-INF/src/denetim/AnasayfaDenetimci.java

Page 14: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

Denetimci sınıfı (AnasayfaDenetimci), denetim paketinin içine koyuyoruz. Bu sınıf, daha önce verileri tutmak için kullanacağımızı   belirttiğimiz  Otopark  sınıfının   araçları   ve   park   yerlerini   tuttuğu   diziyi,   geri   döndürdüğü ModelAndView  nesnesine   ekliyor.   Bu   sınıfa   ilişkin   eklememiz   gereken   diğer   bir   nokta   da   görünümün  (view) springornek/WEB­INF/jsp/anasayfa.jsp olarak belirtilmiş olmasıdır. Bu durumda, anas ayfa olarak kullanacağımız JSP sayfasının adının anasayfa.jsp olması gerekiyor.

Uygulamaya   eklediğimiz   yeni   denetimciyi   kullanabilmek   için   XML   yapılandırma   kütüğümüz   olan  springornek­servlet.xml içinde tanımlamamız gerekiyor (Kod 2.18). 

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans> <bean id="basitDenetimci" class="denetim.BasitDenetimci"/> <bean id="anasayfaDenetimci" class="denetim.AnasayfaDenetimci"/> <bean id="urlEsleme" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/index.htm">anasayfaDenetimci</prop>                <prop key="/basit.htm">basitDenetimci</prop> </props> </property> </bean> <bean id="gorunumCozumleyici" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass"> <value>org.springframework.web.servlet.view.JstlView</value> </property> <property name="prefix"><value>/WEB-INF/jsp/</value></property> <property name="suffix"><value>.jsp</value></property> </bean></beans>

Kod 2.18 springornek/WEB-INF/springornek-servlet.xml

Görüldüğü gibi artık  index.htm adresi yeni yazacağımız ana sayfayı görüntülemek üzere anasayfaDenetimci'ye yönlendirilecek. 

Kod   2.19'da  anasayfa.jsp'ye   yer   veriliyor.   Bu   sayfada  AnasayfaDenetimci'nin  araclar  anahtarı   ile ModelAndView nesnesine eklediği araç dizisini JSTL etiketleri ve JSP EL sözdizim kurallarını kullanarak erişiliyor. Bir döngüyle kılavuzun tüm elemanları geziliyor ve tüm park yeri numaralarına karşılık orada bulunan aracın plakası listeleniyor, eğer araç bilgisi  null  değerine sahipse ilgili park yeri numarasına karşılık  Boş  ifadesi kullanılıyor. Bu şekilde park numaralarının kullanımda olma durumu kullanıcı tarafından takibi kolaylaştırılıyor. Araç listesinin altında ise   yeni   bir   araç   kaydının   yapılabilmesine   yönelik   bir   bağlantıya   yer   veriliyor.   Bu   bağlantının   adresi   olan aracgiris.htm'yi  daha ileride gerçekleştireceğiz. Şu anda araç  ekleme sayfası  aktif  durumda olmadığı   için  tüm park yerleri boş (null) durumda bulunuyor (Resim 2.3).

<%@ page contentType="text/html; charset=ISO-8859-9" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9"> <title>springornek</title></head><body>

<h2>Spring MVC - Otopark Uygulaması</h2> <table>

Page 15: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

<tr height="50"> <td colspan="2"><h3>Araçlar</h3></td> </tr> <c:set var="i" value="1"/> <c:forEach items="${araclar}" var="arac"> <tr> <td width="40">${i}.</td> <c:if test="${arac != null}">

<td>${arac.ilKodu} ${arac.harfKodu} ${arac.aracNo}</td> </c:if> <c:if test="${arac == null}"> <td><em>Boş</em></td> </c:if> </tr> <c:set var="i" value="${i + 1}"/> </c:forEach> </table> <br> <a href="<c:url value="aracgiris.htm"/>">Araç Girişi</a></body></html>

Kod 2.19 springornek/WEB-INF/jsp/anasayfa.jsp

Form KullanımıDaha önce Spring MVC'nin farklı ihtiyaçlara cevap verebilecek nitelikte farklı denetimci sınıf seçenekleri sunduğundan bahsetmiştik   ve   özellikle   formlar   içeren   sayfalarda   form   verilerinin   denetimi,   değerlendirilmesi   ve   kullanılması konusunda kolaylıklar getiren form denetimci sınıfları vurgulamıştık. Uygulamamızda bunlardan çok kullanışlı olan ve tüm   ihtiyaçlarımıza   cevap   veren  org.springframework.web.servlet.mvc.SimpleFormController sınıfını kullanacağız. Örnekler üzerinde inceleyince daha iyi anlaşılacabilecek olmasına rağmen biraz daha derli toplu biçimde   faydalı   olabileceği   için   aşağıda  bu   sınıfın  kullanımı   için  önemli  olan     bazı  noktalar  hakkında  özet  bilgi verilmektedir. 

SimpleFormController  sınıfı  formView  ve  successView  adlı iki nitelik içerir. Bunlara genellikle   XML 

Resim 2.3 Ana Sayfa

Page 16: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

yapılandırma kütüğündeki  denetimci   tanımının  içerisinde   ilk  değer  ataması  yapılır.  Bu niteliklerden  ilki  denetimci tarafından denetlenecek olan formu içeren sayfaya ilişkin görünümün adıdır. Yani denetimciye yönelik bir istek geldiği zaman doğrudan, kullanılacak olan formu içeren bu  görünüm görüntülenir . İkinci nitelik ise form işlemleri başarılı bir şekilde sonuçlanırsa yönlendirilecek olan görünümü belirlemek üzere öngörülmüştür. Bu görünüm formView niteliği örneğinde   olduğu   gibi   otomatik   olarak   görüntülenmez,   ancak   geliştirici   isterse   bu   nitelikle   belirlenen   görünüme yönlendirme yapar (ModelAndView ile kullanarak). Aslında successView niteliğinin kullanımının tercih edilmesinin nedeni değer atamasın XML içerisinde yapılabilmesi ve böylece gidilecek görünümün adının kodun içine gömülmesine gerek kalmamasıdır.

SimpleFormController'ın XML içinde ilklendirilebilen çok önemli iki niteliği daha vardır;  commandName ve commandClass. Bunları belirtmeden önce Spring MVC'deki komut  (command)  sınıflarının açıklanması gerekiyor. Spring MVC, bir  formda kullanıcının   girdiği  verilerin doğrudan bir Java nesnesinin (komut  nesnesi) nitelikleri  ile ilişkilendirilmesine (bağlama / bind)   sağladığı bir takım etiketler (tag) aracılığıyla izin verir ve bu sayede ilgili form alanının içeriği nesnenin niteliğinin değeri olarak kaydedilir. Komut nesneleri adı verilen bu nesnelerin kullanımı, form verilerinin   istek  (request)  nesnesinden   çıkartılıp   başka   bir   Java   nesnesine   kaydedilmesi   işini   geliştiricinin yükümlülüğünden tamamen çıkartan çok pratik bir işlevdir. Ayrıca bu nesneler çeşitli amaçlara yönelik (örneğin verileri doğrulama  (validation))   işlevlerde de Spring'in  sağladığı  yöntemler  sayesinde doğrudan kullanılabilirler  ve bu yapı geliştiriciye çok önemli kolaylıklar sağlar. Sözünü ettiğimiz commandName ve  commandClass nitelikleri de form tarafından   kullanılacak   olan   komut  (command)  nesnesinin   adı   ve   sınıfıdır.   Bu   niteliklere   genellikle   yapılandırma kütüğünde ilk değer atamaları  yapılır.  Eğer  commandName  niteliğine burada yer  verilmezse komut nesnesinin adı varsayılan olarak command olur ve nesneye görünümün içerisinden isimle erişim sağlanır. Komut nesnesinin sınıfını belirten commandClass niteliği yapılandırma kütüğünde belirlenmişse ihtiyaç olduğunda otomatik olarak bu sınıftan boş bir nesne oluşturulur ve kullanılır, buna alternatif bir çözüm ise denetimci sınıf içerisinde daha sonra açıklanacak olan  formBackingObject  yöntemininin   yeniden   yazılmasıdır(override).   Komut   nesnesi   ile   ilgili   olarak vurgulanması gereken diğer önemli bir nokta değerinin null olmasına izin verilmemesidir.   

SimpleFormController  sınıfı   isteğin  (request)  değerlendirilip   yönlendirilmesi   sürecinin   farklı   noktalarında otomatik olarak çağrılan ve  genellikle  bu sınıftan  türetilen denetimci  sınıflar   tarafından yeniden yazılan  (override) yöntemler içerir. Bunlardan önemli olan bazılarını kısaca özetleyelim:

• Object formBackingObject(HttpServletRequest);

Formun komut nesnesinin yapılandırma kütüğünde commandClass niteliği ile belirlenmesi durumunda bu sınıfın   varsayılan   yapılandırıcısı   (default   constructor)   kullanılarak   bir   olgusunun   oluşturularak   formda kullanıldığını   söylemiştik.   Bu   nitelik   belirtilmiş   olsun   veya   olmasın   denetimci   sınıfın   içinde  formBackingObject  yönteminin yeniden yazılması  durumunda bu yöntemin döndürdüğü  nesne  komut  nesnesi olarak kullanılır. Bu sayede, komut nesnesine bir takım ilk değerler vermek suretiyle (örneğin veri  tabanından gerekli  veriler  çekilerek)  bu verilerin   formların  ilişkilendirildikleri   (bağlandıkları)  alanlarında  varsayılan olarak görüntülenmesi sağlanabilir. Burada dikkat edilmesi gereken, yöntemin geriye null değer  döndürmemesi şartıdır, aksi durumda bir çalışma zamanı hatası ortaya çıkar. Anlaşılacağı üzere bu daha form  görünümü görüntülenmeden önce çağrılan bir yöntemdir.

• Map referenceData(HttpServletRequest);

Bu yöntem komut nesnesinin içinde taşınması gereksiz olan verilerin görünüme iletilmesi amacıyla kullanılır.  Yani   formla   ilgisiz  olan  ama  görünüm    tarafından   (görüntülenmek  amacıyla)   kullanılacak  olan  verilerin  iletilmesini   sağlar.   Doğrudan  Controller'dan   türetilen   denetimcilerin  handleRequest  yönteminde ModelAndView  nesnesine verileri eklemesine benzetilebilir. Yöntemin döndürdüğü Map nesnesindeki tüm  veriler yine bu nesnedeki anahtar sözcükleri kullanılarak görünüme (formView) geçirilirler. Yine anlaşılacağı  üzere form görünümü görüntülenmeden önce çağrılan bir yöntemdir.

• ModelAndView onSubmit(HttpServletRequest,HttpServletResponse,Object,BindException);

Bu yöntem yeniden yazılması olmazsa olmazlardan biridir ve formdan bir submit isteği geldiğinde yapılması  gerekenleri gerçekleştirildiği ve işlem sonucunda gidilmesi gereken sayfaya yönlendirmenin yine döndürülen  ModelAndView  nesnesi sayesinde yapıldığı    yöntemdir. Form işlemlerinin tamamen sonuçlandığı  yöntem olduğu söylenilebilir.

Bir   form   denetimci   tarafından   formun   ele   alınmasına   ilişkin   akışla   ve   sağlanan   diğer   yöntemlerle   ilgili   detaylı açıklamaları Spring kurulumunuzun  docs/api  kılavuzunun altında bulunan  javadoc  belgelerinde bulabilirsiniz. Bunun yanısıra, bu belgeleri geliştirme sırasında önemli bir başvuru kaynağı olarak kullanabilirsiniz.

Page 17: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

Araç GirişiYeni bir aracın otoparka girişinin gerçekleştirildiği sayfa aracın plakasına ilişkin üç alanın girilmesine ve uygun bir park yerinin seçilmesine olanak veren bir form içermelidir. İşlem gerçekleştirildikten sonra, verilerde bir hata yoksa, listenin son durumunu görmek üzere tekrar ana sayfaya dönülmesini öngörüyoruz. Bir form denetimcisi yazmadan önce komut sınıfını yazalım. Bu arada komut sınıfları için komut adlı bir paket oluşturduğumuza dikkat edin (Kod 2.20). 

Form   üzerinde   araca   dair   bilgilerle   (örneğimizde   sadece   plaka   alanları)   aracın   otoparkta   hangi   park   yerine   park edildiğine dair bilgiler girileceği için komut sınıfımızda (AracGirisi) bir Arac nesnesi ve park yeri için bir tam sayı bulunuyor. Tabi bu sınıfın komut sınıfı olarak kullanılabilmesi için niteliklerine okuma ve yazma izni veren JavaBean tanımına uygun erişim yöntemleri (set/get) gerçekleştirilmelidir.

package komut;

import ismantigi.Arac;

public class AracGirisi {

Arac arac;int parkYeri;

public Arac getArac() {return arac;

}public void setArac(Arac arac) {

this.arac = arac;}public int getParkYeri() {

return parkYeri;}public void setParkYeri(int parkYeri) {

this.parkYeri = parkYeri;}

}

Kod 2.20 springornek/WEB-INF/src/komut/AracGirisi.java

Kod 2.21'de araç girişi sayfasını ele almakta kullanacağımız  AracGirisFormDenetimci  sınıfına yer verilmiştir. Bu sınıfta daha önce sözünü ettiğimiz üç yönteme de yer verildiğini görüyoruz. 

package denetim;

import ismantigi.Otopark;import komut.AracGirisi;

import java.util.HashMap;import java.util.Map;

import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;

import org.springframework.validation.BindException;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.mvc.SimpleFormController;import org.springframework.web.servlet.view.RedirectView;

public class AracGirisFormDenetimci extends SimpleFormController {

protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response,Object command,BindException errors)

Page 18: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

throws Exception {

AracGirisi aracGirisi = (AracGirisi)command;Otopark.aracParket(aracGirisi.getArac(), aracGirisi.getParkYeri());return new ModelAndView(new RedirectView(getSuccessView()));

}

protected Map referenceData(HttpServletRequest request)throws Exception {

Map veri = new HashMap();veri.put("araclar", Otopark.getAraclar()); return veri;

}

protected Object formBackingObject(HttpServletRequest request)throws Exception {

AracGirisi aracGirisi = new AracGirisi();aracGirisi.setArac(new Arac());aracGirisi.setParkYeri(Otopark.getIlkBosYer());return aracGirisi;

}}

Kod 2.21 springornek/WEB-INF/src/denetim/AracGirisFormDenetimci.java

Bu yöntemlerden formBackingObject yöntemi komut sınıfı olan AracGirisi sınıfının nesnesini oluşturduktan sonra ilk değer atamaları yapmak amacıyla gerçekleştirilmiştir. Oluşturulan yeni AracGirisi nesnesinin parkYeri niteliğinin   değeri  Otopark  sınıfının  ilkBosYer  niteliğinin   değeri   ile   kurulmaktadır.   Böylece   JSP   sayfasında varsayılan   olarak   bu   değerin   kullanıcıya   sunulması   sağlanacaktır   ve   kullanıcı   isterse   sadece   plaka   alanlarını doldurmakla yetinecek ve uygun park yeri seçimi yapmasına gerek kalmayacaktır. 

Yeniden yazılan diğer  bir yöntem olan  referenceData  yöntemi  ise  form görünümünün  ihtiyacı  olan araç  park yerleri   verisinin   gönderilmesi   amacı   gütmektedir.   Görünüme   yine  Otopark  sınıfında   tutulan   araç   dizisi gönderilmektedir. Bu bilgi görünüm tarafından, kullanıcıya kolaylık sağlamak amacıyla, park yerlerini bunlardan dolu veye boş olanları ayırt edilebilecek biçimde farklı renklerde sunmak amacıyla kullanılacaktır.

Son olarak onSubmit yöntemi form üzerinde ilgili düğmenin tıklanarak araç girişi olayının tetiklenmesi ile çağrılır. Bu yönteme gelen argümanlardan birinin Object türündeki command nesnesi olduğunu görüyoruz. Bu nesne, formda kullanılan komut nesnesidir ve ileride JSP sayfasını incelerken göreceğimiz üzere forma girilen verilerle araç ve park yeri   niteliklerinin   değerleri   kurulmuş   olarak   bu   yönteme   gelir.   Komut   nesnesi  Otopark  sınıfının   araç   girişini kaydetmek amacıyla kullanılan aracParket yönteminin ihtiyacı olan araç ve park yeri verilerini sağlar. Gerçek bir uygulamada   bunun   yerine   örneğin   bir   veri   tabanı   güncellemesi   yapılabilirdi.   Geri   döndürülen  ModelAndView nesnesine herhangi bir veri eklenmezken, bu nesnedeki görünümün successView niteliği ile belirlendiği görülüyor, bu   niteliğin   değeri   daha   önce   söz   edildiği   gibi   yapılandırma   kütüğünde   kurulması   öngörülmektedir. SimpleFormController'dan   türeyen   sınıflar   için   bile   bu   niteliğe   doğrudan   erişim   izni   olmadığı   için getSuccessView yöntemi kullanılmaktadır.

RedirectView

Kod   2.21'de   görünümün   doğrudan   görünüm   adı   ile   belirtilmesi   yerine   görünüm   adı   ile   oluşturulan   bir RedirectView  nesnesinin kullanıldığını görüyoruz. İlk kullanımda (görünüm adı kullanımı) isteğin  (request) kontrolü aynen  başka bir noktaya yönlendirilir veya devredilir (forward). Bu durumda eğer post yöntemini kullanan bir form   bu şekilde yönlendirilmişse kullanıcı sayfayı her yenilediğinde aynı istek tekrar işletilir. Daha açık bir ifade ile kullanıcı ekranında artık form değil  örneğin işlem sonucunu yansıtan bir sayfa vardır, ancak kullanıcı sayfayı yenilediği zaman üretilen istek form tarafından oluşturulan isteğin aynısıdır ve bu ­ genellikle istenmeyen bir şekilde ­ bir kez gerçekleştirilmesi  gereken bir işlemin tekrar edilmesine neden olur. Kritik bir uygulamada bu önemli   sakıncaları   olabilir.  Yeniden  yönlendirme  (redirect)  yaklaşımının  kullanılması   ile  yönlendirilen   sayfaya gidilirken  belirtilen  url'ye   tamamen yeni  bir   istek  oluşturularak  yönlendirme  gerçekleşir.  Yani   form  tarafından üretilen istekten tamamen bağımsız yeni bir istek oluşturularak yeni sayfaya gidilir. Bu kullanımda dikkat edilmesi 

Page 19: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

gereken  nokta  yönlendirme  bir   görünüm adı   ile  değil     görünüme  ilişkin   adres   ile  yapılır   ve  successView niteliğinin değerinin bu göz önüne alınarak belirlenmesi gerekir.  

Sonuç   olarak,   yapılandırma   kütüğünde  AracGirisFormDenetimci  için   eklenilen   tanımlamaları   Kod   2.22'de görebilirsiniz.   İlk   olarak  aracGirisFormDenetimci  adıyla   tanımladığımız   denetimciyi   url   eşleme   kısmında aracgiris.htm  adresi   ile   eşleştirildiğini   vurgulayalım   (ana   sayfanın   en   altında   bulunan   bağlantıyı   hatırlayın!).   Bu denetimci  tanımının  içinde komut nesnesinin adının  aracGiris  olduğu ve bunun  AracGirisi  türünde olduğu görülüyor. Ayrıca formun aracgiris.jsp içerisinde bulunduğu, dolayısıyla bu denetimciye yönelik istekler geldiğinde bu sayfanın görüntülenmesi talebi belirtiliyor. Son olarak  successView  niteliği ile form işlemleri başarılı bir şekilde tamamlandığında   yeniden   yönlendirmenin  (redirect)  yapılacağı   adresin   bu   XML   kütüğü   içerisinde   belirlendiğini görüyoruz.

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="basitDenetimci" class="denetim.BasitDenetimci"/><bean id="anasayfaDenetimci" class="denetim.AnasayfaDenetimci"/>

<bean id="aracGirisFormDenetimci"

class="denetim.AracGirisFormDenetimci"> <property name="sessionForm"><value>true</value></property> <property name="commandName"><value>aracGirisi</value></property> <property name="commandClass"> <value>komut.AracGirisi</value> </property> <property name="formView"><value>aracgiris</value></property> <property name="successView"><value>index.htm</value></property> </bean>

<bean id="urlEsleme" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/index.htm">anasayfaDenetimci</prop> <prop key="/basit.htm">basitDenetimci</prop> <prop key="/aracgiris.htm">aracGirisFormDenetimci</prop> </props> </property> </bean> <bean id="gorunumCozumleyici" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass"> <value>org.springframework.web.servlet.view.JstlView</value> </property> <property name="prefix"><value>/WEB-INF/jsp/</value></property> <property name="suffix"><value>.jsp</value></property> </bean> </beans>

Kod 2.22 springornek/WEB-INF/springornek-servlet.xml

Şimdi sıra aracgiris.jsp'yi gerçekleştirmeye geldi. Bu sayfada komut nesnesi niteliklerini form alanlarına bağlayabilmek (bind)  için Spring'in etiket kütüphanesini kullanmamız gerekiyor, bunun için de yapılması gereken bir kaç  küçük iş bulunuyor.  Önce etiket  kütüphanesi   tanımlayıcısı  kütüğü  olan  spring.tld  kütüğünü  kurulumunuzun  dist  kılavuzunun altından   (örneğin   benim   için  spring­framework­1.2.5/dist/spring.tld)   uygulamanızın  WEB­INF  kılavuzunun   içine 

Page 20: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

kopyalayın. Uygulamanın bu kütüphanenin kullanımına izin vermesi için web.xml kütüğüne de bir ekleme yapmamız gerekiyor (Kod 2.23). Artık bu etiket kütüphanesini bir JSP içerisinde kullanabilmek için tek satırlık bir   kod yeterli olacaktır (taglib directive). Artık Kod 2.24'te verilen aracgiris.jsp'yi uygulamaya ekleyip yeniden çalıştırabilir ve sonucu aracgiris.htm adresinde görebilirsiniz (Resim 2.4).

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.4">

<servlet> <servlet-name>springornek</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet

</servlet-class><load-on-startup>1</load-on-startup>

</servlet><servlet-mapping>

<servlet-name>springornek</servlet-name> <url-pattern>*.htm</url-pattern>

</servlet-mapping><welcome-file-list>

<welcome-file>index.jsp</welcome-file></welcome-file-list><taglib>

<taglib-uri>/spring</taglib-uri> <taglib-location>/WEB-INF/spring.tld</taglib-location>

</taglib></web-app>

Kod 2.23 springornek/WEB-INF/web.xml

<%@ page contentType="text/html; charset=ISO-8859-9" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ taglib prefix="spring" uri="/spring" %>

<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9"><title>springornek - Araç Girişi</title></head><body> <h2>Spring MVC - Otopark Uygulaması</h2> <h3>Araç Girişi</h3> <form method="post"> <table cellspacing="10"> <tr>

<td>Araç Plakası:</td> <td> <spring:bind path="aracGirisi.arac.ilKodu">

<input type="text" style="width:30;" name="${status.expression}" value="${status.value}">

</spring:bind> <spring:bind path="aracGirisi.arac.harfKodu">

<input type="text" style="width:40;" name="${status.expression}" value="${status.value}">

</spring:bind> <spring:bind path="aracGirisi.arac.aracNo">

<input type="text" style="width:40;" name="${status.expression}" value="${status.value}">

</spring:bind> </td></tr><tr>

Page 21: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

<td>Park Yeri:</td> <td> <spring:bind path="aracGirisi.parkYeri"> <select name="${status.expression}">

<c:set var="i" value="0"/> <c:forEach items="${araclar}" var="arac"> <option value="${i}" "${i == status.value ? "selected" : ""}" <c:if test="${arac != null}"> style="background-color:GREY;" </c:if> >${i + 1}</option> <c:set var="i" value="${i + 1}"/> </c:forEach>

</select> </spring:bind> </td></tr><tr> <td colspan="2" align="right"> <input type="submit" value="Kaydet"> </td>

</tr> </table> </form> <a href="<c:url value="index.htm"/>">Ana Sayfa</a></body></html>

Kod 2.24 springornek/WEB-INF/jsp/aracgiris.jsp

Gördüğünüz gibi sayfa plakanın ve park yerinin girilmesi için alanlar ve submit türünde, araç girişinin kaydedilmesini tetikleyen   bir   düğmeyi   içermekte.   Dikkat   ettiyseniz  form  etiketinin   içinde   herhangi   bir  action  niteliğine   yer verilmemiştir, çünkü form zaten tamamen denetimcinin kontrolündedir ve düğmenin tıklanması halinde ne yapılması gerektiği de denetimci tarafından belirlenir (onSubmit yönteminin çalıştırılması gibi).  

Aslında bu JSP sayfasında  spring:bind etiketileri ve bunların içinde kullanılan  status  adlı değişken dışında yenilik bulunmuyor. Plaka alanları text türündeki input alanlarından oluşuyor, park yeri numaraları ise bir select etiketi   ile   görüntüleniyor.   Park   yeri   numaraları   JSTL  forEach  etiketi   kullanılarak   araclar   adlı   (denetimcinin referenceData yöntemini hatırlayınıız) liste üzerinde dolaşırken sayaç olarak kullanılan bir  i değişkeni ile select etiketinin   içerisine   bu  park  numarasına   ilişkin  option  etiketi   ekleniliyor.   Araç   listesinin  kullanımı   ise  option etiketinin içeriği dikkatli incelenirse sıradaki aracın değeri null değilse – yani o park yeri dolu ise – bu seçeneğin gri renkte görüntülenmesi amacını taşıyor. 

Daha önce söz ettiğimiz bağlama işlemi spring:bind etiketi ile gerçekleştiriliyor. Bu etiketi kullanmak için 

<%@ taglib prefix="spring" uri="/spring" %>

satırını eklemeyi unutmamanız gerekiyor. İsterseniz bu etiketin kullanımını satır satır inceleyelim. 

<spring:bind path="aracGirisi.arac.ilKodu">

satırı bağlamanın başlangıcıdır ve path niteliği ile ilgili form alanının komut nesnemiz olan aracGirisi'nin arac değişkeninin ilKodu niteliği ile bağlanacağını ifade ediyoruz. 

<input type="text" style="width:30"

name="${status.expression}" value="${status.value}">

Input etiketi ile il kodunun girilebilmesi için 30 piksel genişliğinde text türünde bir alan tanımı yapıyoruz. Bu alanın adının  ve  değerinin  belirlenmesinde  status  değişkeninin  kullanıldığını   görüyoruz.  Bu değişken  bind  etiketinin içerisinde  Spring   tarafından  tanımlanan  bir  değişkendir  ve  expression  ve  value  ile  örneklediğimiz  bir   takım nitelikler sağlar. Bunlardan expression çoğunlukla form alanının isimlendirmede kullanılan bir deyimi ifade eder. Genelde   değeri   komut   nesnesinin   bağlanılan   niteliğinin   adıdır,   mesela   örneğimizde  arac.ilKodu    değerine   sahip olacaktır. Bu şekilde, geliştiricinin kendisinin belirleyeceği form alanı isimlerini daha sonra istek (request) nesnesinden verileri parametreler olarak çıkartırken hatırlaması zorunluluğu ortadan kalkmış oluyor. 

Page 22: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

Kullandığımız   diğer   nitelik   olan  value  ise   form   alanına   bir   değer   vermekte   kullanılıyor.   Bu   niteliğin   önemini kavramak için bir veri güncelleme sayfası düşünelim. Genelde veri güncelleme sayfalarında alanlara ilişkin daha önce girilmiş olan verilerin görüntülenmesi gerekir. Bunu gerçekleştirmek için ise daha çok eski verileri sayfaya parametre olarak göndermek, bu verilerin değerinin  null  veya anlamsız olup olmadığı kontrolünü yapmak ve sakıncası yoksa form alanlarının değeri olarak bu değerleri kullanmak gibi kodu gerçekten kabartan ve anlaşılmaz hale getiren eklemeler yapmamız gerekir. Tüm bu sorunları açıklamaya çalışığımız value niteliğinin yukarıdaki gibi kullanımı çözmektedir. Çünkü status.value değişkenine otomatik olarak komut nesnesinin ilgili niteliğinin değeri koyulur. İlk olarak artık bu   veriyi   sayfaya   parametre   olarak   gönderme   ihtiyacı   ortadan   kalkar,   çünkü   zaten   elimizde   olan   komut   nesnesi kullanılmaktadır.  Diğer  bir  gelişme ise artık böyle bir parametrenin var  olup olmadığı  varsa değerinin  null  olup olmadığı kontrolüne gerek kalmaz. Çünkü bu kullanımda değerin  null  olup olmadığı Spring tarafından denetlenir, eğer değilse bu değer ilgili alanda görüntülenir.

</spring:bind>

Bu satır bind etiketinin sonlandığı noktadır ve bağlama işlemi için gereken kod tamamlanmıştır. Bağlama işlemi ile birlikte formdan submit  isteği üretildiği zaman form alanındaki değer komut nesnesinin ilgili niteliğinin değeri olarak kurulur  ve komut nesnesine erişilen her yerden bu değere erişilir. Görüldüğü gibi artık örneğin form verisi kullanılarak veri tabanında yapılacak bir güncelleme için istek nesnesinin parametrelerini almak ve değişkenlerin içerisine koymak için satırlarca kod yazmanıza gerek yok. Çünkü her şey gereken komut nesnesinin içine yerleşmiş durumdadır.   Bunu zaten denetimcinin onSubmit yönteminin içerisindeki 

Otopark.aracParket(aracGirisi.getArac(), aracGirisi.getParkYeri());

satırı ile örneklemiştik.

Diğer ilginç ve güzel bir örnek de select alanını çevreleyen bind etiketinin kullanımıdır. Bu sefer komut nesnesinin parkYeri  alanını  select  etiketi   ile bağlıyoruz ve bu değer sonuç  olarak seçilen değerle kuruluyor.  Daha önce güncelleme sayfalarında görebileceğimizden söz ettiğimiz eski (veya varsayılan) değerin sayfada yüklenmesini de

<option value="${i}" "${i == status.value ? "selected" : ""}"

satırı ile örnekliyoruz. Gördüğünüz gibi tüm park yerlerini listelemek için bir sayaç olarak kullandığımız i değişkeninin parkYeri niteliğinin değerine sahip olan status.value  ile karşılaştırılıyor, eğer eşitlik varsa option etiketinin içine seçili olmasını sağlamak amacıyla  selected  anahtar sözcüğü ekleniyor. Bu sayede, örneğin ilk defa 1 no'lu park yerine   bir araç girişi yaptıktan sonra tekrar araç girişi sayfasına geldiğinizde park yeri seçiminde varsayılan olarak 2 değeri  görüntülenir.  (Kod 2.17'de verilen  Otopark  sınıfındaki  aracParket  yönteminde  ilkBosYer  niteliğinin değerinin her araç girişinde ilk boş park yerinin değeri ile kurulduğunu hatırlayın.) 

Resim 2.4 Araç Girişi Sayfası

Page 23: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

Doğrulama (Validation)Lütfen plakanın il kodu veya araç alanına bir tam sayı olmayan bir değer girerek veya boş bırakarak araç girişi yapmayı deneyin. İşlemin tamamlanamadığını ana sayfa yerine araç girişi sayfasında kaldığınızı görerek anlamış olmalısınız. Bu Spring   tarafından   otomatik   olarak   yapılan,   beklenilen   veri   türü   (tamsayı)   ile   girdinin   veri   türünün   uyuşmaması nedeniyle işlemin gerçekleştirilmesine izin vermeyen veri doğrulaması (validation) nedeniyle olmuştur.

Yukarıda   açıklanan   işlev   aslında   geliştiriciyi   bir   çok   zahmetten   kurtarmaktadır.   Çünkü   form   verilerinin   türlerinin kontrol edilmesi, dönüştürme sırasında fırlatılan aykırı durumların ele alınması ve kullanıcıya bu hatanın sonucu ile geri dönülmesi gibi hacim kaplayan bir çok kodlama işlemlerinin otomatikleşmesi sağlanıyor. 

Ancak biraz düşününce bunların yeterli olmadığı açıktır. Bir uygulamada iş mantığı veya veri tutarlılığı gibi bir çok konuda   farklı   denetimler   gerekebilir,   ayrıca   bu   denetimler   sonucu   fark   edilen   hataların   giderilmesi   veya   tekrar edilmemesi için kullanıcıya mutlaka geri bildirimde bulunulması gerekmektedir. Tabi Spring'in hata denetimi desteği de bu kadarla kalmamakta, sözü edilen iki konuyla ilgili etkili çözümler sunulmaktadır.

Spring'in MVC kısmından bağımsız olan org.springframework.validation paketi veri doğrulama işleminde kullanılır. Bu paketin içindeki  Validator arayüzünden türetilen ve parametre olarak aldığı komut nesnesi üzerinde doğrulama   işlemlerini   yerine   getirebildiği  validate  yöntemini   gerçekleştiren   sınıfların   nesneleri   bir   form denetimcisinin validator niteliği olarak kullanılabilir. Tahmin ettiğiniz gibi bu tanımlamalar doğrulama yapan sınıf yazıldıktan sonra yapılandırma kütüğü üzerinde gerçekleştirilir.

Kendi uygulamamızı göz önüne aldığımızda tür denetiminin dışında mantıksal denetimler yapmamız gerektiği açıktır. Bunları şu şekilde listeleyebiliriz:

• Plakanın il kodu kesimi 1 – 81 (Ocak 2006 itibarı ile) arasında bir tamsayı olmalıdır. 

• Plakanın araç numarası kesimi 1 – 9999 aralığında bir tamsayı olmalıdır.

• Plakanın harf kodu kesimi ise 1 – 3 adet (büyük) harften ibaret olmalıdır.

• Dolu bir park yerine başka bir araç park edilemez.

Uygulamamızda veri doğrulama amaçlı sınıflarımızı koyabileceğimiz  dogrulama  paketini oluşturduktan sonra Kod 2.25'te verilen ve bu kontrolleri gerçekleştiren Validator türevi sınıfı buraya kaydedebilirsiniz.

package dogrulama;

import ismantigi.Otopark;import komut.AracGirisi;

import org.springframework.validation.Errors;import org.springframework.validation.Validator;

public class AracGirisDogrulayici implements Validator {

public boolean supports(Class c) {return c.equals(AracGirisi.class);

}

public void validate(Object command, Errors errors) {

AracGirisi aracGirisi = (AracGirisi)command; if(Otopark.doluMu(aracGirisi.getParkYeri()))

errors.rejectValue("parkYeri", "parkYeriDolu");

if(aracGirisi.getArac().getIlKodu() < 1 || aracGirisi.getArac().getIlKodu() > 81)

errors.rejectValue("arac.ilKodu", "gecersizIlKodu");

if(aracGirisi.getArac().getHarfKodu().length() > 3)errors.rejectValue("arac.harfKodu", "harfKoduUzunlukHatasi");

if(!aracGirisi.getArac().getHarfKodu().matches("[A-Z]*"))

Page 24: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

errors.rejectValue("arac.harfKodu","harfKoduKarakterHatasi");

if(aracGirisi.getArac().getAracNo() < 1 || aracGirisi.getArac().getAracNo() > 9999)

errors.rejectValue("arac.aracNo", "gecersizAracNo")}

}

Kod 2.25 springornek/WEB-INF/src/dogrulama/AracGirisDogrulayici.java

İsterseniz bu kodu ele almadan önce doğrulama amalı sınıfımızın tanımlanıp  AracGirisDenetimci  ile bağlama etiketlerini eklememiz   gereken yapılandırma kütüğünün son durumunu görüp doğrulamanın nasıl gerçekleştirildiğini açıklığa kavuşturalım (Kod 2.26).

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="basitDenetimci" class="denetim.BasitDenetimci"/> <bean id="anasayfaDenetimci" class="denetim.AnasayfaDenetimci"/> <bean id="aracGirisDogrulayici" class="dogrulama.AracGirisDogrulayici"/>

<bean id="aracGirisFormDenetimci" class="denetim.AracGirisFormDenetimci"> <property name="sessionForm"><value>true</value></property> <property name="commandName"><value>aracGirisi</value></property> <property name="commandClass"><value>komut.AracGirisi</value></property> <property name="validator"><ref bean="aracGirisDogrulayici"/></property> <property name="formView"><value>aracgiris</value></property> <property name="successView"><value>index.htm</value></property> </bean> <bean id="urlEsleme" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/index.htm">anasayfaDenetimci</prop> <prop key="/basit.htm">basitDenetimci</prop> <prop key="/aracgiris.htm">aracGirisFormDenetimci</prop> </props> </property> </bean> <bean id="gorunumCozumleyici" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass"> <value>org.springframework.web.servlet.view.JstlView</value> </property> <property name="prefix"><value>/WEB-INF/jsp/</value></property> <property name="suffix"><value>.jsp</value></property> </bean> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename"><value>mesajlar</value></property> </bean> </beans>

Kod 2.26 springornek/WEB-INF/springornek-servlet.xml

Yapılandırma   kütüğünde   görüldüğü   gibi   öncelikle   doğrulayıcı   sınıf   için   bir   çekirdek  (bean)  tanımlanıyor 

Page 25: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

(aracGirisDogrulayici). Sonra bu doğrulayıcı aracGirisDenetimci'nin validator niteliği tarafından işaret ediliyor. Dikkat ederseniz doğrudan bir değer vermek yerine çekirdeğe işaret edildiği için ref etiketi kullanılıyor. Artık form denetimcinin bir doğrulayıcısı vardır ve formdan bir submit isteği geldiğinde öncelikle bu doğrulayıcının validate yöntemi çağrılır ve sonuç olarak bir hata belirlenmişse istek geri çevrilerek form tekrar görüntülenir (ve sakıncası yoksa ­şifre alanı vs. değilse­ kullanıcı tarafından  girilmiş olan veriler gösterilir). 

Şimdi  doğrulayıcı   sınıfın   içeriğini   tartışabiliriz.  Bu  sınıfta  gerçekleştirilen   ilk  yöntem  supports  yöntemidir.  Bu yöntem doğrulayıcıya verilen bir komut nesnesinin bu doğrulayıcı tarafından ele alınıp alanıamayacağını belirlemek için kullanılır.   Onun   için   hemen   her   doğrulayıcı   bu   yöntemin   içeriğini   aynı   şekilde   fakat   farklı   bir   komut   sınıfı   ile gerçekleştirir.

Diğer yöntem olan  validate'in iki argümanı vardır. Bunlardan  Object  tütündeki  command  komut nesnesidir ve görüldüğü gibi biz onu  AracGirisi  türüne çevirerek kullanıyoruz. Diğer argüman ise form üzerinde ortaya çıkan hataların tutulduğu errors nesnesidir. Bu nesnenin içeriği sadece bu yöntem tarafından belirlenmez, daha önce söz ettiğimiz gibi Spring'in otomatik olarak gerçekleştirdiği denetimlerle bulunan hatalar da bu nesnenin içinde bulunur. sonuç  olarak bu nesneye kaydedilmiş  hata(lar)  varsa  submit  işlemi gerçekleştirilmez ve form yeniden görüntülenir. Yöntemin içerisinde yukarıda listelenen, iş mantığına dair bir takım kontroller yapılıyor ve eğer hatalı bir durum varsa bu errors nesnesinin içerisine  rejectValue yöntemi çağrılarak ekleniyor. Bu yönteme verilen iki parametreden ilki komut nesnesinin hataya sebep olan niteliğinin adıdır. İkincisi ise ortaya çıkan hataya ilişkin kullanılan bir anahtar kelimedir. Bu anahtar örneğin görüntülenecek hata mesajının belirlenmesinde kullanılabilir.   Spring'in ilgili javadoc belgeleri incelenirse  Errors   ve  ValidationUtils  sınıflarının sağladığı kullanışlı  bir takım yöntemlerin daha bulunduğu görülebilir.

Mesaj konusuna değinmişken yapılandırma kütüğüne eklediğimiz bir diğer çekirdek (bean) olan messageSource'a değinmemiz   gerekiyor.   Bu   aslında   Spring   çatısının   yine   MVC'den   bağımsız   olarak   sağladığı   bir   çözümdür   ve org.springframework.context.support.ResourceBundleMessageSource  sınıfının   bir   nesnesidir. Burada bu işlevin sadece konumuz kapsamında, örneğimiz içindeki kullanımına yer vereceğiz. Çekirdek tanımında yer alan  basename  niteliğine   görüldüğü   gibi  mesajlar  değeri   atanıyor.   Bu   tanım   uygulamada   mesajların mesajlar.properties adlı kütüğün içinde bulunduğunu ifade eder. Kısaca açıklamak gerekirse (uzantısı .properties olan) properties kütükleri  her satırda birbirinden “=” işareti ile birbirinden ayrılan anahtar değer çiftlerinden oluşan, sade ve pratik bir şekilde bu değerleri kaynak kodun içerisine gömülmekten kurtaran bir çözümdür ve sadece Spring tarafından değil Java tarafından her tür uygulamada kullanımı desteklenen bir standarttır. Biz içeriğini Kod 2.27'de görebileceğiniz mesajlar.properties  kütüğünü  /WEB­INF/classes  kılavuzunun  altına  koyuyoruz  ve   yapılandırma  kütüğündeki   tanım sayesinde Spring tarafından anahtar kelimelere karşılık gelen mesajları  içeren  mesajKaynağı(messageSource)  olarak algılanmasını   sağlıyoruz.     Dikkat   edilmesi   gereken   bir   nokta   standartlar   gereği   bu   kütükte   yer   alan   bazı   Türkçe karakterlerin   algılanamaması   nedeniyle  onlara   Unicode   değerleri   ile   yer   veriyoruz  (İ=\u0130,   ı=\u0131,  Ş=\u015E, ş=\u015F, Ğ=\u011E, ğ=\u011F).

typeMismatch=Geçersiz veri!typeMismatch.ilKodu=\u0130l kodu bir tamsay\u0131 olmal\u0131!typeMismatch.aracNo=Araç no bir tamsay\u0131 olmal\u0131!parkYeriDolu=Seçti\u011Finiz park yeri dolu!gecersizIlKodu=\u0130l kodu 1-81 aras\u0131nda olmal\u0131!harfKoduUzunlukHatasi=Harf kodu en fazla 3 karakter içerebilir!harfKoduKarakterHatasi=Harf kodu yaln\u0131z A..Z aras\u0131ndaki karakterleri içerebilir!gecersizAracNo=Araç no 1-9999 aras\u0131nda olmal\u0131!

Kod 2.27 springornek/WEB-INF/classes/mesajlar.properties

Burada söz edilmesi  gereken bir  nokta da Spring tarafından tanımlanan  typeMismatch  anahtarıdır.  Kod 2.27'de bizim   belirlediğimiz   anahtarlardan   biri   olmayan   bu   anahtar   bir   tür   dönüşümü   hatası   ortaya   çıktığı   zaman   Spring tarafından üretilir.  typeMismatch  tek başına tüm tür dönüşümü hatalarına karşılık gelirken, istenirse niteliğe özel hata mesajlarına yer verebilmek için typeMismatch.ilKodu örneği gibi bir kullanım tercih edilebilir. 

Komut nesnesini kullanarak veri denetimini nasıl yapabileceğimizi gördük. Hataların kullanıcıya bildirilmesinde ise yine   Spring   etiketlerine   başvuracağız.   Biz   örneğimizde  spring:bind  etiketinin   yanısıra spring:hasBindErrors etiketini kullanarak hata geri bildirimini örnekleyeceğiz. Örneğimizde yer almayacak olsa da  hasBindErrrors'un   sağladığı  errors  değişkeninin   (bind  etiketinin  status  değişkeninin   bir   benzeri) errorCount,  allErrors gibi niteliklerinin de faydalı kullanımları olabileceğini hatırlatmak gerekir. Tüm Spring etiketleri   hakkında   detaylı   bilgi   için   Spring   kurulumunuzun  docs/taglib  kılavuzu   altındaki   belgelerden yararlanabilirsiniz. Şimdi biz üzerine bazı eklemeler yaparak geliştirdiğimiz  aracgiris.jsp'de kullanıcıya yönelik hata 

Page 26: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

bildirimini nasıl ele aldığımızı görelim (Kod 2.28).

<%@ page contentType="text/html; charset=ISO-8859-9" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ taglib prefix="spring" uri="/spring" %>

<html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9"> <title>springornek - Araç Girişi</title></head><body> <h2>Spring MVC - Otopark Uygulaması</h2> <h3>Araç Girişi</h3>

<form method="post"> <table cellspacing="10"> <tr> <td valign="top">Araç Plakası:</td> <td> <spring:bind path="aracGirisi.arac.ilKodu"> <input type="text" style="width:30;" name="${status.expression}" value="${status.value}">

</spring:bind> <spring:bind path="aracGirisi.arac.harfKodu"> <input type="text" style="width:40;"

name="${status.expression}" value="${status.value}"> </spring:bind> <spring:bind path="aracGirisi.arac.aracNo">

<input type="text" style="width:40;" name="${status.expression}" value="${status.value}">

</spring:bind> <font color="red" size="2px"> <spring:bind path="aracGirisi.arac.*"> <c:forEach items="${status.errorMessages}" var="error">

<br>${error} </c:forEach>

</spring:bind> </font>

</td> </tr> <tr> <td valign="top">Park Yeri:</td> <td>

<spring:bind path="aracGirisi.parkYeri"> <select name="${status.expression}"> <c:set var="i" value="0"/> <c:forEach items="${araclar}" var="arac"> <option value="${i}" "${i == status.value ? "selected" : ""}" <c:if test="${arac != null}">

style="background-color:GREY;" </c:if> >${i + 1}</option> <c:set var="i" value="${i + 1}"/> </c:forEach> </select>

<font color="red" size="2px"> <c:forEach items="${status.errorMessages}" var="error">

<br>${error} </c:forEach>

</font>

Page 27: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

</spring:bind> </td> </tr> <tr> <td colspan="2" align="right"> <input type="submit" value="Kaydet"> </td> </tr> </table> </form>

<spring:hasBindErrors name="aracGirisi"> <font color="blue"><h5> Lütfen hatalı girişleri düzeltiniz! </h5></font> </spring:hasBindErrors>

<a href="<c:url value="index.htm"/>">Ana Sayfa</a>

</body></html>

Kod 2.28 springornek/WEB-INF/jsp/aracgiris.jsp

Görüldüğü gibi plaka alanlarına dair hataların listesi tablonun plaka alanlarının bulunduğu hücresinde, park yerine dair hata mesaj(lar)ı da park yerine dair hücrede görüntüleniyor.  Hata mesajlarını göstermede  bind  etiketinin sağladığı status  değişkeninin  daha  önce   söz   etmediğimiz  errorMessages  niteliğinden  yararlanıyoruz.  Bu nitelik   liste türündedir ve mesajlar bu liste üzerinde dolaşılarak görüntülenir. Plaka alanlarına ilişkin hataların görüntülendiği 

    <spring:bind path="aracGirisi.arac.*">

      <c:forEach items="${status.errorMessages}" var="error">

              <br>${error}

            </c:forEach>

    </spring:bind>

kısımda komut  nesnesinin  ara  niteliğinin  tüm niteliklerine  (arac.*;  plaka alanları)  dair  bir  bağlama  (bind)  işlemi yapılıyor. Buradaki komut nesnesi niteliklerini herhangi bir form alanına bağlama işlemi yoktur, sadece onlara ilişkin hata mesajlarına erişebilmek amacı güdülmektedir. Park yeri seçimi ile ilgili hatalar ise

          <c:forEach items="${status.errorMessages}" var="error">

      <br>${error}

    </c:forEach>

satırları ile görüntüleniyor. Dikkat ederseniz burada yeni bir  bind  etiketi kullanılmıyor, çünkü  parkYeri niteliğini form   alanı   ile   bağlamak   için   açılan   etiket   henüz   kapatılmadı   ve   varsa   ona   ilişkin   hatalara   burada status.errorMessages üzerinden erişilebiliyor. Son olarak 

<spring:hasBindErrors name="aracGirisi">

<font  color="blue"><h5>

Lütfen hatalı giri leri düzeltiniz!ş

</h5></font>

</spring:hasBindErrors>

satırlarında hasBindErrors etiketinin sanki bir if deyimi gibi davranarak, komut nesnesinin herhangi bir niteliği için girdi hatası bulunmuşsa bunların giderilmesini öneren bir mesaj görüntülenmesinde kullanımı örneklenmektedir. Resim 2.5'te hata geri bildirimine ilişkin bir örnek ekran görüntüsü bulunmaktadır.

Page 28: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

Durdurucular (Interceptors)Durdurucu kavramı Spring'in işleyici eşleme  (handler mapping)  mekanizması ile birlikte düşünülen bir işlevdir. Bir isteği   uygun   denetimciye   yönlendiren   işleyici   eşleme   nesnesinin  (handler   mapping)  içerisinde org.springframework.web.servlet.HandlerInterceptor  arayüzünü   gerçekleştiren   durdurucu sınıflarının   nesneleri   bulunabilir.   Bu   arayüz  preHandle,  postHandle  ve  afterCompletion  yöntemlerini sağlar. Bunlardan preHandle uygun denetimci çalıştırılmadan önce, postHandle denetimci çalıştırıldıktan sonra, ama görünüme yönlendirilmeden önce, afterCompletion ise istek tamamen gerçekleştirildiğinde çağrılır.

Uygulamamızda durdurucuları  örneklemek  için  otoparkta  yeni  araç  girişi   için  boş  yer  kalmadığı   zaman araç  giriş sayfasına  gelen   isteklerin  değerlendirilmeden ana  sayfaya  yönlendirilmesi   senaryosunu ön görüyoruz.  Bu durumda durdurucunun işlemleri preHandle yönteminin içinde gerçekleştirmesi gerektiği ortaya çıkıyor. Çünkü bir denetimci (aracGirisFormDenetimci)   çalıştırılmadan   önce   onun   çalıştırılıp   çalıştırılamayacağınca   karar   verilmesi   söz konusu. Ancak burada ortaya çıkan bir problem daha var; tüm denetimciler aynı işleyici eşleme nesnesi tarafından ele alındığı için tüm denetimcilere gelen istekler durdurucu tarafından park yeri kalıp kalmadığı sorgusuyla karşı karşıya kalacaklardır.   Bunu   çözebilmek   için   içerisinde   sadece  aracGirisDenetimci'sinin   eşlemesinin   ve   durdurucu tanımının yer aldığı yeni bir işleyici eşleme tanımına ihtiyacımız olacaktır. Kod 2.29'da durdurucu sınıfın içeriğine yer verilmiştir.

package denetim;

import ismantigi.Otopark;

import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;

Resim 2.5 Veri Doğrulama ­ Hata Geri Bildirimi

Page 29: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

public class AracGirisDurdurucu implements HandlerInterceptor {

protected String hataSayfasi;

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

if(Otopark.doluMu()) {response.sendRedirect(hataSayfasi);return false;

}return true;

}

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

}

public void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)throws Exception {

}

public String getHataSayfasi() {return hataSayfasi;

}

public void setHataSayfasi(String hataSayfasi) {this.hataSayfasi = hataSayfasi;

}}

Kod 2.29 springornek/WEB-INF/src/denetim/AracGirisDurdurucu.java

Gördüğünüz gibi  preHandle  yönteminin içerisinde  Otopark  sınıfının  doluMu  yöntemi çağrıılıyor ve otoparkın dolu olup olmadığı denetleniyor. Eğer dolu ise araç giriş sayfasını görüntüleyecek olan denetimci çalıştırılmamalıdır, bu nedenle geriye false döndürülmektedir. Tabi denetimcinin çalıştırılmaması durumunda görüntülenecek olan sayfanın beirlenmesi   gerekmektedir.   Bu   amaçla   eğer   otopark   dolu   ise  hataSayfasi  niteliğinde   tutulan   adrese   (yeniden yönlendirme   /   redirect   yapıldığı   için   bir   adres   verilmesi   gerekiyor)   yönlendirme   gerçekleştiriliyor.   Bu   niteliğin tutulmasının   sebebi   gidilecek   sayfayı   kodun   içi   yerine,   yapılandırma   kütüğüne   yazmanın   tercih   edilmesidir.   Eğer otopark dolu değilse hiç bir şey yapılmasına gerek yoktur ve true döndürülür, bu da aracGirisDenetimci'nin çalıştırılmasına izin verir.

Kod 2.30'da yapılandırma kütüğünde yapılan değişiklikleri görebilirsiniz.

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="basitDenetimci" class="denetim.BasitDenetimci"/> <bean id="anasayfaDenetimci" class="denetim.AnasayfaDenetimci"/> <bean id="aracGirisDogrulayici" class="dogrulama.AracGirisDogrulayici"/>

<bean id="aracGirisFormDenetimci" class="denetim.AracGirisFormDenetimci"> <property name="sessionForm"><value>true</value></property> <property name="commandName"><value>aracGirisi</value></property>

Page 30: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

<property name="commandClass"><value>komut.AracGirisi</value></property> <property name="validator"><ref bean="aracGirisDogrulayici"/></property> <property name="formView"><value>aracgiris</value></property> <property name="successView"><value>index.htm</value></property> </bean>

<bean id="urlEsleme" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/index.htm">anasayfaDenetimci</prop> <prop key="/basit.htm">basitDenetimci</prop> </props> </property> </bean> <bean id="aracGirisDurdurucu" class="denetim.AracGirisDurdurucu"> <property name="hataSayfasi"><value>index.htm</value></property> </bean> <bean id="aracGirisUrlEsleme" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="interceptors"> <list>

<ref bean="aracGirisDurdurucu"/></list>

</property> <property name="mappings"> <props> <prop key="/aracgiris.htm">aracGirisFormDenetimci</prop> </props> </property> </bean> <bean id="gorunumCozumleyici" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass"> <value>org.springframework.web.servlet.view.JstlView</value> </property> <property name="prefix"><value>/WEB-INF/jsp/</value></property> <property name="suffix"><value>.jsp</value></property> </bean> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename"><value>mesajlar</value></property> </bean> </beans>

Kod 2.30 springornek/WEB-INF/springornek-servlet.xml

Artık  aracGirisFormDenetimci'ye   gelen   istekler  urlEsleme  adlı   işleyici   eşleme   nesnesi   tarafından   ele alınmıyor, onun yerine  aracGirisUrlEsleme  adlı yeni eklediğimiz nesne kullanılıyor. Bu nesne işleyici eşleme özelliğinin   yanı   sıra  aracGirisiDurdurucu'nun   da   dikkate   alınmasından   sorumlu   tutuluyor.   Dikkat   edilmesi gereken   diğer   bir   husus   da  aracGirisiDurdurucu'nun  haftaSayisi  niteliğinin   değerinin   burada anasayfa.htm olarak belirlenmesidir.

Son değişikliklerin ardından uygulamayı çalıştırıp, otopark tamamen doluncaya kadar araç girişi yapar ve ardından ana sayfadaki araç girişi bağlantısını tekrar tıklarsanız araç girişi sayfasına yönlendirilmediğinizi, hala ana sayfada kalmaya devam ettiğinizi görebilirsiniz.

Page 31: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

SonuçEğer  belgeyi  baştan   sona  dikkatlice,  örnekleri  çalıştırarak  ve  hatta  üzerinde  oynamalar  yaparak  okuduysanız  artık Spring  MVC çatısının   temel  kavram ve   işlevleri  hakkında  önemli  derecede   fikir   sahibi  olduğunuzu söyleyebiliriz. Başlangıç düzeyinde hazırlanan bu belgede, Spring MVC ile acısız bir şekilde tanışılması hedefiyle, önemli kavramlara ve öğrenme döneminde sorun çıkartabileceği düşünülen noktalara öncelik tanıyarak yer verilmeye çalışıldı.  

Belgenin içerisinde de sık sık belirtildiği gibi burada bir çok konuda Spring MVC'nin sağladığı tüm seçeneklere yer vermek yerine en sık kullanılanara değinilmeye ve örneklerde bunların kullanımına özen gösterildi. Böyle bir tercih yapılmasının sebebi öğrenme döneminde kafa karışıklığının ortaya çıkmasından sakınmaktı. Ancak şu andan itibaren sağlanılan tanışıklılık sayesinde başvuru belgesi (reference manual), javadoc belgeleri vb. geniş kapsamlı kaynaklardan yararlanmakta zorluk çekilmeyeceği ön görülebilir.

Bundan sonraki aşamada uygulamaya burada yer vermediğimiz araç çıkışı işlevini sağlayan bir sayfayı eklemek ve veri üzerindeki işlemlerin bir veri tabanına taşımak faydalı denemeler olabilir. 

Spring'in sağladığı esnek ve yapılandırılabilir yapı sayesinde Spring MVC'nin gücü Spring'in veri tabanı desteği veya daha   farklı   bir  çok konuda   sağladıkları   ile  birleştirilerek  çok yetenekli   uygulamalar  ortaya  çıkartılabilir.  Spring'in Hibernate benzeri veri tabanı teknolojilerini, çeşitli görünüm teknolojilerini ve hatta Struts'la birlikte çalışmayı ve daha bir   çok   farklı   teknolojiyi   desteklediğini   de   göz   önüne   aldığımızda   ufkunun   ne   kadar   geniş   olduğu   ve   kullanım yaygınlığının  daha  uzun   süre   artarak  devam edeceği   ortaya  çıkıyor.  Bu  durumda  henüz   işin  başında  olduğumuzu söylemek sanırım yanlış olmaz.

 

Page 32: Spring MVC Uygulama Catisi OSUNERCAN WwwJavaDiliCom

Terimler SözlüğüAttribute NitelikBean ÇekirdekBind BağlamaCommand(Class) Komut Container KozaConstructor YapılandırıcıController Denetimci  Design Pattern Tasarım ÖrüntüsüDirectory Kılavuz (Kütük)File KütükFront Controller Ön Denetimci Handler  İşleyiciHandler Mapping İşeyici Eşleme Implement (an Interface) Uygulamak(Array) Index DizinInterceptor DurdurucuInterface ArayüzMap HaritaMapping EşlemeMethod YöntemOverride Yeniden yazmakPackage PaketRedirect Yeniden YönlendirmeRequest İstekResponse YanıtTag EtiketValidation Doğrulama View GörünümView Resolver Görünüm Çözümleyici

Kaynaklarhttp://www.springframework.org/docs/reference/

http://www.ociweb.com/

http://www.theserverside.com/articles/article.tss?l=SpringFramework

http://www.devx.com/Java/Article/22134/0/page/1

http://www.128.ibm.com/developerworks/web/library/wa­spring3/