You are on page 1of 32

Spring MVC Uygulama Çatısı

Ömer SUNERCAN
omersunercan.cs@gmail.com

2006, Ankara
İçindekiler
Giriş......................................................................................................................................................3
Belge İçeriği Hakkında....................................................................................................................3
Spring MVC..........................................................................................................................................3
Geliştirme Ortamının Hazırlanması.................................................................................................3
Kurulum......................................................................................................................................3
Uygulama Kılavuz Yapısının Oluşturulması...............................................................................4
Başlangıç (DispatcherServlet).........................................................................................................4
İlk Spring MVC Örneği...................................................................................................................5
Uygulamaya Başlıyoruz.................................................................................................................11
Ana Sayfa.......................................................................................................................................13
Form Kullanımı..............................................................................................................................15
Araç Girişi......................................................................................................................................17
Doğrulama (Validation).................................................................................................................23
Durdurucular (Interceptors)...........................................................................................................28
Sonuç..................................................................................................................................................31
Terimler Sözlüğü................................................................................................................................32
Kaynaklar............................................................................................................................................32
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 MVC
Bu 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. 
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. 
<?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ği
Spring 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 
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 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 
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 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.
Ş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.

Resim 2.1 Başlangıç Sayfası

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


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

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

Uygulamaya Başlıyoruz
Artı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 
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?
}
}
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 Sayfa
Uygulamamı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


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>
<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

Resim 2.3 Ana Sayfa

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 
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.
Araç Girişi
Yeni 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)
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 
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 
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>
<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. 
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ı
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]*"))
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 
(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 
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>
</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.
Resim 2.5 Veri Doğrulama ­ Hata Geri Bildirimi

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;
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>
<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.
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.
 
Terimler Sözlüğü
Attribute Nitelik
Bean Çekirdek
Bind Bağlama
Command(Class) Komut 
Container Koza
Constructor Yapılandırıcı
Controller Denetimci  
Design Pattern Tasarım Örüntüsü
Directory Kılavuz (Kütük)
File Kütük
Front Controller Ön Denetimci 
Handler  İşleyici
Handler Mapping İşeyici Eşleme 
Implement (an Interface) Uygulamak
(Array) Index Dizin
Interceptor Durdurucu
Interface Arayüz
Map Harita
Mapping Eşleme
Method Yöntem
Override Yeniden yazmak
Package Paket
Redirect Yeniden Yönlendirme
Request İstek
Response Yanıt
Tag Etiket
Validation Doğrulama 
View Görünüm
View Resolver Görünüm Çözümleyici

Kaynaklar
http://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/

You might also like