Bu Blogda Ara

20 Mayıs 2010 Perşembe

Spring Framework - Web MVC / NetBeans 6.8 / Bölüm 2

Not: Bu yazı Spring Framework - Web MVC / NetBeans 6.8 adlı yazının devamı niteliğindedir.

Bir önceki yazımda kaldığım noktadan devame etmeye çalışacağım. Giriş yazımda bir Spring Web MVC projesini NetBeans 6.8 ile oluşturmuştuk. Şimdi yapıyı incelemeye devam edeceğiz. WEB-INF dizini altındaki ayar dosyalarını inceleyerek devam edelim.


İlk olarak Web.xml den biraz bahsetmek istiyorum. Bu dosya Java Web projelerinde genel ayarların yapıldığı standart bir dosyadır. Tıpkı Asp.NET projelerindeki Web.config dosyası gibi. Arzu ederseniz içeriğine bir gözatalım.


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
</web-app>


İlk bakışta göze batan karmaşıklık sizi korkutmasın. Aslında anlaması gayet basit. Burada XML formatında ayarlar mevcut. Şimdilik bu dosya salt okunur gibi olmalı. Buradan herhangi bir ayarı değiştirmeyelim. Aksi takdirde uygulamamız doğru çalışmayabilir. Fakat anlamadan da geçemeyiz. Eğer bu detayları iyi kavramazsak, frameworke tam olarak hakim olamayız. context-param kısmında projemiz için içerik ayarlarının yapıldığı düğümdür. Buraya contextConfigLocation adında bir anahatar ve /WEB-INF/applicationContext.xml şeklinde bir değer girilmiştir. Bu dosya Spring projemizde yapacağımız bazı ayarların (veritabanı bağlantı cümleleri vb.) bulunacağı dosya. listener düğümünde dinleyici sınıfları belirtiyoruz. Değer olarak org.springframework.web.context.ContextLoaderListener sınıfı eklenmiş. Daha sonra bir servlet tanımlanmış. dispatcher adındaki bu servlet Spring'in temel çözümleme servlet sınıfıdır. Sınıfın yolu org.springframework.web.servlet.DispatcherServlet şeklinde eklenmiş. servlet-mapping düğümü ile hangi servlet hangi desenle (örüntü - pattern) eşleceği belirtiliyor. dispatcher servleti için *.htm şeklinde bir desen verilmiş. Daha önceki yazımda belirtiğim noktaya geldik. Kullanıcı web tarayıcısıyla web sunucumuza *.htm şeklinde bir sorgu yaptığı zaman web sunucumuz bunu anlayarak ilgili servleta (burada dispatcher oluyor) yönlendirecektir. Son olarak welcome-file-list düğümü ile sitemiz ilk açılışta hangi sayfayı direk gösterecek onu belirtiyoruz. Örneğin Apache web sunucusunda varsayılan karşılama dosyası index.html, index.htm ya da index.php, IIS sunucusunda default.html, default.htm, default.asp ya da default.aspx şeklinde olabilir. NetBeans otomatik olarak redirect.jsp dosyasını seçmiş. Bu kısmı dilediğiniz gibi (desene uygun bir URL ile) edeğiştirebilirsiniz.



NetBeans Web.xml için görsel ayar penceresi


Şimdi gelelim dispatcher-servlet.xml dosyamıza. Bu dosya Web.xml dosyasında belirtiğimiz dispathcer servlet sınıfı için ayar niteliğindedir. Vakit kaybetmeden içeriğine bir göz atalım.


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>

<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.htm">indexController</prop>
</props>
</property>
</bean>

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />

<!--
The index controller.
-->
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />

</beans>


İlk baştaki uzun tanımlamaları direk atlıyorum. Şimdilik bu ayarlar konumuz değil. Olduğu gibi bırakıyoruz.

bean tagıyla başlayan satırda yeni Spring bean sınıfını (org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping) tanımlıyoruz. Alt satırdaki yorum bu satırları anlamamız için önemli. Yorum satırında bu eklediğimiz sınıfın (ControllerClassNameHandlerMapping) bir çok kontrollör sınıf tarafından kullanıldığından fakat indexController sınıfı için ParameterizableViewController sınıfının kullanıldığını bu yüzden harici bir rota belirlememiz gerektiğinden bahsetmektedir.
Bir alt satırda org.springframework.web.servlet.handler.SimpleUrlHandlerMapping sınıfının tanımlanmasıyla görebiliyoruz. Verdiği değerler önemli. index.htm şeklinde gelen bir isteğin indexController nesnesi tarafından yorumlanacağı bu satırda belirtilmektedir. Siz burayı dilediğiniz gibi değiştirebilirsiniz. Örneğin merhaba.htm yapabilirsiniz. Dikkat etmeniz gereken bir nokta olarak dosya uzantısı .htm olaması söylenebilir. Unutmayalım Web.xml dosyasında dispatcher servlet için *.htm şeklinde bir desen belirlemiştik. Buna uymak zorundayız.
Bir sonraki satırda viewResolver sınıfının tanımlandığını görüyoruz. Bu çok önemli özellikle yapıyı idrak etme hususunda. class="org.springframework.web.servlet.view.InternalResourceViewResolver" Spring'in dahili kaynak görüntü çözümleyici sınıfı. p:prefix="/WEB-INF/jsp/" ve p:suffix=".jsp" satırları dışardan gelen istekleri uygulamamızın iç yapısında nereye karşılık geldiğini gösterir. prefix (öntakı) değeri ile görüntülerin dizinini suffix(son ek) ile yerel dosyaların uzantısını belirtiyoruz. Yani dışarıdan gelen index.htm şeklindeki bir sorgu dispatcher servleta söylediğimiz *.htm şeklindeki desene uygun olarak parçalanır ve index kelimesi görüntü olarak elde edilir. Bir önceki satırda belirtilen rotaya uyun olarak (index.htm -> indexController), bir sonraki satırda inceleyeceğimiz görüntü<->kontrollör tanımlaması ile index görüntüsü olduğu karar kılınır. Sonra /WEB-INF/jsp/index.jsp dosyası (indexController denetiminde) görüntü olarak açılır.
Bir sonraki satırda (az önce de söylediğim gibi) görüntü<->kontrollör tanımlaması yapılmakta. name="indexController" ile kontrollör adını, class="org.springframework.web.servlet.mvc.ParameterizableViewController" ile kullanılacak sınıfı (burada hazır sınıf kullandık, kendi sınıfımızı oluşturup bu sınıftan kalıtım da alabilirdik), p:viewName="index" ile görüntü adını belirtiyoruz.

Ayarlarla ilgili kısmı burada noktalıyorum. Bir sonraki yazımda görüntü ve kontrollör oluşturma ve kullanma konularına değineceğim inşallah. Anlatımda kusurum varsa affınıza sığınıyorum.
Görüşmek üzere...

16 Mayıs 2010 Pazar

Yığın Veri Yapısı

Merhabalar,
Bu yazımda yığın veri yapısından bahsetmek istiyorum. Çalışması LIFO (Last In First Out - Son Giren İlk Çıkar) ilkesine dayanmaktadır. Fiziksel bir örnek vermek gerekirse yalnızca bir tek arabanın geçebileceği kadar genişlikte olan çıkmaz bir sokağa arabaların ard arda girmesi gibidir. Son giren araba ilk çıkmalıdır ki diğer arabalar çıkabilsin.

Peki Ne İşe Yarar?
Günümüzde bir çok sistem hafıza yönetiminde bu veri yapısını kullanmaktadır. Özellikle sıranın önemli olduğu durumlarda. Mesela, programlama dillerinde açtığımız parantezlerin kapatılıp kapatılmadığının kontrolü, işletim sistemi düzeyinde fonksiyonların çağrımı sırasında parametrelerin aktarımı, aritmetik işlemlerde işlem önceliğinin sağlanması ( çarpmanın toplamaya üstünlüğü), karakter katarlarının ters çevrilmesi vb. bir çok alanda kullanılmaktadır.

Teknik olarak açıklamak gerekirse...
Belirli bir hafıza bölgesini programcıdan soyutluyoruz. Direk erişimi engelliyoruz. Programcıya hafızaya erişmesi için fonksiyonlar veriyoruz. Bunlar push, pop ve isEmpty olabilir. Sırasıyla açıklayalım.
  • Push
Yığına bir eleman eklemek istediğimizde bu fonksiyonu çağırırız. Fonksiyona veridiğimiz değer yığının en sonuna eklenir.
  • Pop
Yığından bir eleman çekmek için kullanılır. Bu fonksiyon bize yığının en sonundaki yani son eklediğimiz elemanı yığından alır bize verir. Daha önceki elemanlara erişmek için Pop fonksiyonunu çağırmaya devam etmeliyiz. Bu fonksiyon herhangi bir parametre almaz.
  • isEmpty
Bu fonksiyon ile yığının boş olup olmadığını kontrol edebiliriz.
Siz fonksiyonlarınıza istediğiniz ismi verebilirsiniz. Korumanız gereken tek şey LIFO ilkesidir. Geri kalan kısmı değiştirmekte özgürsünüz.

Hemen Java ile bir örnekleme yapalım:

package test;

import java.util.ArrayList;

class Stack
{
private ArrayList<Object> objectList; // nesneleri tutacak generic yapımız.

public Stack()
{
objectList = new ArrayList<Object>(); // nesnemizi üretelim.
}

public boolean isEmpty()
{
return objectList.isEmpty(); // liste boş ise yığında boştur.
}

public void Push(Object obj)
{
objectList.add(obj); // yığına eleman ekleyelim.
}

public Object Pop()
{
if (objectList.isEmpty())
return null; // yığın boş ise eleman çekemeyiz. Sonuç null değeri.
Object o = objectList.get(objectList.size()-1); // sondan bir elemanı alalım.
objectList.remove(objectList.size()-1); // sonra bu elemanı yığından çıkartalım.
return o; // geriye döndürelim.
}
}


public class Main{

public static void main(String[] args) {

Stack s = new Stack();
if (s.isEmpty())
System.out.println("yığın boş.");
s.Push(5);
if (s.isEmpty())
System.out.println("bu satırı görmememiz gerekiyor.");
s.Push(45);
System.out.println(s.Pop());
System.out.println(s.Pop());
System.out.println(s.Pop());
System.out.println(s.Pop());
if (s.isEmpty())
System.out.println("yığında eleman yok.");
}

}




En basit haliyle böyle gerçeklenebilirdi sanırım. Veri yapılarını açıklamaya devam edeceğim.
Görüşmek üzere...

15 Mayıs 2010 Cumartesi

Intel 8085 Mikroişlemci / Başlangıç

Herkese merhaba,
Bu yazımda Intel firması tarafından geliştirilmiş olan 8085 mikroişlemcisi yapısı, çalışma prensibi ve programlanması ile ilgili genel bilgi vereceğim. Başlıkta da belirttiğim gibi bu mikroişlemciler ve micro programlama konusuna girişimin imgesidir. Öncelikle bu basit mikroişlemciyi inceleyip programlamasına değineceğim. Daha sonra yine Intel firmasının 8051 mikrodenetleyicisinden bahsedeceğim. Daha sonraki yazılarımda sayısal sistemleri en başından alıp bir mikroişlemci nasıl çalıştığını anlatacağım. Daha sonra kendi mikroişlemcimi tasarlayacağım. Umarım atlamadan anlaşır bir biçimde anlatabilirim. Siz de üzerinde çalışıp kendi mikroişlemcinizi geliştirebilirsiniz.

Intel 8085 8-bit Microprocessor


Her konuda olduğu gibi bu konuda da tarihsel bilgilerle vaktinizi çalmak gibi bir niyetim yok. Merak edenler varsa http://en.wikipedia.org/wiki/8085 adresinden gerekli bilgileri alabilir. Programlama kısmına geçmeden önce işlemcinin yapısı hakkında bilgi vermek doğru olacaktır. Başlamadan önce belirtmeliyim. Bu yazımda sadece mikroişlemcinin yapısı ve programlamasından bahsedeceğim. Elektronik bir devrede nasıl kullanıldığından vb. diğer işlemlerden bahsetmeyeceğim. Genel olarak soyut sorunlar üzerinden yola çıkacağız.


Yukarıdaki şema mikroişlemcinin iç yapısını göstermektedir. Sırayla açıklayalım...
  • 8 bit veri yolu
İşlemci birimleri arası haberleşmeyi sağlayan ortak kanal olarak tanımlanabilir. Bir seferde 8-bit veri taşıyabilir ve yalnızca tek bir birim kullanabilir. Bu birim kanala veriyi bırakır, veri yolunun bağlı olduğu tüm birimlere veri iletiri fakat yalnızca o anda ona ihtiyacı olan birim o veriyi kullanır. Tıpkı Ethernet (IEEE 802.3) protokolünde olduğu gibi. Burada farklı bir durum olarak veriyi kullanacak birimin aktif diğerlerinin pasif olamasını işlemci ayarlamaktadır. Toparlamak gerekirse, bir broadcast (yayın) tipi iletişim var fakat bu yayına yalnızca ilgili birim aldırış ediyor.
  • ALU (Arithmetic Logic Unit)
Diğer bir değişle Ardışıl Mantık Birimi. Bu birimde tüm mantıksak ve aritmetik işlemler yapılmaktadır. Toplama, çıkarma, karşılaştırma vb.
  • Accumulator (Akümülatör)
Temel kaydedici olarak tanımlasam çok yanlış olmaz sanırım. Tüm aritmetik işlem sonuçları bu kaydedicide saklanmaktadır. 8-bit veri saklayabilmektedir. Bir çok işlemde bu kaydedici kullanılmaktadır. Yeri geldikçe detaylandıracağım.
  • Instruction Register
Bu saklayıcı mikroişlemcinin işleyeceği komutu tutar. 8 bitliktir. Bu mikroişlemcinin 8 bit kelime işlemci olduğunu belirtmiştik. Bir seferde bir tek komutu işleyebilmektedir ve bu komut 8 bit (1 byte) olmak zorundadır. Zaten hafıza birimimizin (RAM / ROM) her bir gözü 1 byte boyutundadır.
  • Program Counter
İşlemcinin bir sonraki işleyeceği komutun adresini saklayan kaydedicidir. Boyutu 16 bittir. Buradan şu sonucu çıkartabiliriz, 8085 mikroişlemcisi 16 bit ile adreslenebilecek kadar hafıza alanında kod koşturabilmektedir. 2^16 ~= 64 kb hafıza alanı.
  • Stack Pointer
Yığın hafıza bölgesinin adresini tutar. Buraya FILO (First In Last Out - İlk Giren Son Çıkar) mantığıyla veri ekleyip çıkartabiliyoruz. Boyut 16 bit.
  • Flag Register
Bazı komutlar sonrasında durum kontrolü yapılması gerekmektedir. Örneğin bir toplama işleminde sonuç saklayıcının boyutunu aşabilir. Bu durumda işlemci kilitlenmez işleme devam eder, fakat programcı bu durumdan haberdar olması gerekmektedir. Programcı böyle bir durumun gerçekleşip gerçekleşmediğini Bayrak Saklayıcısındaki taşma bayrağının 1 - 0 durumunu inceleyerek anlayabilir. Bayraklardan kısaca bahsetmek gerekirse;
Sıfır Bayrağı = çıkarma işleminin sonucu 0 ise,
Taşma Bayrağı = toplama işlemi saklayıcıya sığmıyorsa, ya da çıkarılan çıkandan küçükse,
İşaret Bayrağı = Akümülatördeki sayı negatif ise (yani 8. bit 1 ise)
bu bayraklar 1 değerini alır. Aksi durumda 0 değerindelerdir.

Yazıma burada ara veriyorum. Bir sonraki yazımda kaldığım yerden tanıtmaya devam edeceğim. Daha sonra programlama kısmına geçeceğiz. Vaktim olursa bellek organizasyonu konusuna da değineceğim.
Görüşmek üzere...

Bağlı Listeler

Merhabalar,
Bu yazımda sizlere bağlı liste veri yapısından bahsedeceğim. Veri yapısı deyince kulağa egzotik gelebilir. Ama inanın bildiğiniz şeylerden farklı bir şey anlatmayacağım. "Bildiklerimizi bir araya getirerek bilmediğimiz bir yapıyı tanımlama" şeklinde anlıyorum veri yapılarını...

Nedir? Neden gerek duyulmuştur?
Bağlı liste veri yapısı hafızanın farklı bölgelerinde bulunan verileri birbirine katar şeklinde bağlayan yapıdır.Dizi vb. yapılar zaten bu işi sağlamıyor mu? şeklinde bir soru aklınıza tam bu satırda gelmiş olmalı. Evet sağlıyor ama bir yere kadar. Diziler hafızanın belirli bir noktasında ardışıl olarak gelir. Yani dizinin ilk elemanı hafızanın 100 nolu adresinde bulunuyorsa dizinin ikinci elemanı 101 nolu gözde bulunacaktır. Ayrıca diziler ilk oluşturulduğunda uzunluğu belli olmak zorundadır. Daha sonra genişleme imkanı yoktur. Ancak tekrar boyutlandırma yapılabilir ki bu iş oldukça maliyetlidir. İşte böyle dinamik genişleyen ucuz maliyetli bir yapıya ihtiyaç duyulduğu sırada keşfedilmiş olmalı bağlı listeler.

Bağlı derken?
Bağlı listenin her bir elemanı hafızada birbirine bir sonraki elemanın aderesini gösterecek bilgiye sahiptir. Biz yalnızca ilk elemanın adresini biliriz. İkinci elemana ulaşmak için önce birinci elemana gideriz, ondan bir sonraki yani ikinici elemanın adresini alırız daha sonra ikinci elemana ulaşabiliriz. Üç, dört, beş ... hafıza dolana kadar üretilebilir, ulaşım mekanizması hep aynı. Bağlı derken bu mekanizma kastediliyor.

İhtiyaca göre...
Sorunlar farklı olunca çözümler, dolayısıyla gereksinimler de farklı oluyor. Bağlı liste veri yapısı iki çeşittir. Tek yönlü ve çift yönlü. İlkinde sadece ileri yönlü haraket yapmak mümkünken ikinci tipde geri gelme de mümkündür. Siz kendi probleminize en uygun tipi seçmelisiniz.

Bırak gevezeliği de biraz kod yaz!

Tek yönlü bağlı liste, C örneği

#include <stdio.h>
#include <stdlib.h>

typedef struct _eleman
{
struct _eleman *sornakiEleman; // bir sonraki elemanı işaret eder.
int veri; // yapının sakladığı veri. istenilen tipte istenildiği kadar veri eklenebilir.
} eleman;

typedef struct
{
eleman *ilkEleman; // bağlı listeyi temsil eden yapı. Yalnızca ilk elemanı işaret ediyor.
} bagliListe;

bagliListe *bagliListeUret();
void elemanEkle(bagliListe*,int);
void elemanCikart(bagliListe*,int);
void listele(bagliListe*);

int main()
{
bagliListe * bl = bagliListeUret(); // yeni bir bağlı liste ürettik.
elemanEkle(bl,6); // eleman ekleyelim.
elemanEkle(bl,34);
elemanEkle(bl,987);
elemanEkle(bl,5);
elemanEkle(bl,2);
listele(bl); // listele.
system("pause");
elemanCikart(bl,3); // 3. elemanı çıkart. ( ilk eleman 0'dan başlar)
listele(bl); // tekrar listele, farkı gör.
system("pause");
}

bagliListe *bagliListeUret()
{
bagliListe* bl = (bagliListe*)malloc(sizeof(bagliListe)); // yeni bir bağlı listeyi hafızada oluşturup ilgili adresi alıyoruz.
bl->ilkEleman = NULL;
return bl;
}

void elemanEkle(bagliListe* bl,int veri)
{
eleman *e = (eleman*)malloc(sizeof(eleman)); // yeni bir eleman oluşturalım.
e->sornakiEleman = NULL;
e->veri = veri;
eleman *son = NULL; // katarın son elemanı.
son = (eleman *)bl->ilkEleman; // başlangıç elemanını bağlı listeden alalım.
if (son==NULL) // listemiz boş mu?
{
bl->ilkEleman = e;
return;
}
while(son!=NULL) // değilse özyinelemeli olarak son elemana erişmeye çalış.
{
if (son->sornakiEleman==NULL)
break;
son = (eleman*)son->sornakiEleman; // düğümler arası atlama.
}
son->sornakiEleman = e; // nihayet son düğümün işaretçisine kendi adresimizi yazıyoruz.
}

void listele(bagliListe* bl)
{
eleman *e = NULL;
e=(eleman *)bl->ilkEleman;
int i=0;
while(e!=NULL) // özyinelemeli listeleme fonksiyonu.
{
printf("%i. eleman verisi = %i\n",i++,e->veri);
e = (eleman*) e->sornakiEleman;
}
}

void elemanCikart(bagliListe * bl, int sira)
{
eleman *e = NULL;
e=(eleman *)bl->ilkEleman;
eleman *onceki = NULL;
int i=0;
if (e==NULL) // listemiz boş mu?
{
printf("Liste bos oldugu icin cikartma yapilamiyor!\n");
return;
}
while(e!=NULL)
{
if (i==sira)
break;
i++;
onceki = e;
e = (eleman*) e->sornakiEleman;
}
onceki->sornakiEleman = e->sornakiEleman; // silmek istediğimiz elemanın bir önceki düğümü ile bir sonraki düğümü birbirine bağlıyoruz. Böylelikle aradan çekilerek silinmiş izlenimi oluşturuluyor.
free(e); // hafıza sızıntısını önlemek için serbert bıraktığımız elemanı hafızadan silmeyi unutmayalım.

}


Diğer yüksek seviyeli dillerde (Java, C# vb.) bu veri yapısını yapmak çok daha kolay. Mantıktan yola çıkarak o dillerde de sorunsuz bir şekilde bağlı liste veri yapısını oluşturabileceğinize inanıyorum.
Görüşmek üzere...

JQuery ve Sanat

Tekrar merhaba,
Bu yazımda JQuery ile sanat nasıl yapılır konusuna ışık tutmaya çalışacağım. Sanat yapmak derken belki biraz abartmış olabilirim ama abartı çoğu insanın ilgilini çeken bir olgudur. Klasik, nedir - ne değildir zamazingosunu yapalım. Öncelikle resmi sitesini vererek kaynak belirtebiliriz - http://jquery.com/
not: indirirken size 2 seçenek sunmaktadır. Production / development şeklinde. Farkı, ilkinde gereksiz boşluk ve satır atlama karakterleri silinerek dosyanın boyutu küçültülmüş, bir nevi sıkıştırma yapılmış. Fakat kodun okunması neredeyse imkansız çünkü herşey birbirine geçmiş durumda. İkinci seçenekte ise kodlar okunaklı bir şekilde yayınlanıyor. Boyutu ilkine göre daha fazla ama bir geliştirici için çok değerli.
JQuery kütüphane içerisindeki kopyalama hakkı yazısını değiştirmediğiniz sürece ticari uygulamalarda dahi kullanabilirsiniz. Tamamen ücretsiz. Lisans detayları için resmi sitesinden bilgi alabilirsiniz.

Bu aralar çok duymaya başladım, nedir bu JQuery?
Özetle javascript yazımını kolaylaştıran kütüphane. İçerisinde bir çok javascript fonksiyonu barındırıyor. En önemli özelliği tarayıcı bağımsız olması. Yani JQuery ile yazdığımız javascript komutları tüm tarayıcılarda aynı şekilde sorunsuz olarak çalışmaktadır. Web ortamında javascript geliştirenler tarayıcı uyumsuzluğu sorununu bilmektedir. JQuery ile bu ortadan kalkmaktadır. Pratikte JQuery bize yeni birşey değil. Normal javascript komutlarıyla yapacaklarımızdan ötesi yok. O bize hızlı, güvenilir ve tarayıcı bağımsız javascript geliştirme imkanı sunmaktadır.

Hızlı bir giriş

$(document).ready(function(){
$("a").click(function(event){
alert("Tum linkler bu yaziyi gosterir!");
});
});

Sırayla inceleyelim. Öncelikle $ karakterinden başlamak istiyorum. Bu fark edebileceğiniz gibi bir fonksiyon aslında. Bildiğimiz javascript fonksiyonu. JQuery için temel ifade ediyor. Tüm çağrılarımızı bu fonksiyon üzerinden yapıyoruz. Reguler Expression tanımlamalarını çok iyi kullandıkları için bu fonksiyonun içerisine verebileceğimiz parametrelerin sayısı oldukça fazla. $(document) ile javascript'in çalıştığı dosyayı seçiyoruz. Daha sonra gelen .ready(... ifadesiyle sayfamızın işlem için hazır olduğunu garantiliyoruz.
function() { } neden gerekli?
.ready olayında çalışmasını istediğimiz kodları direk parantez içerisinde yazsaydık kodumuz çalışmayacaktı. Çünkü JQuery çalışma mantığında bir iş yapmak için o işi yapacak fonksiyonun adını ilgili JQuery fonksiyonuna vermeliyiz. Aynı fonksiyon işaretçileri gibi ya da diğer bir benzetmeyle klasik setTimeout javascript komutunda olduğu gibi.
Şimdi biraz toparlayalım:
$(document) // sayfamız
.ready( // hazır olunca çalıştır
function() { ... } // yeni bir fonksiyon ürettik ve bağladık
);

İyi gidiyoruz, ya sonra?
Yeni oluşturduğumuz fonksiyonun içeriğini inceleyelim.
$("a") // a taglı elemanları seç.
.click( // tıklayınca çalıştır.
function() { ... } // yeni bir fonksiyon ürettik ve bağladık
);
Burada oluşturduğumuz fonksiyonun içerisine alert komutumuzu yerleştirdik.
Kodumuzu çalıştırdığımızda sayfamızdaki tüm linkler tıklandığında bu mesajı alacaklar.
Giriş olarak bu kadarla yetineceğim. Daha sonraki yazılarımda detaylı incelemeler ve yeni örnekler sunacağım.
Görüşmek üzere...

Spring Framework - Web MVC / NetBeans 6.8

Herkese merhaba,
Bu yazımda sizlerle Spring Framework ile mvc web uygulamalarına giriş yapacağız. Amacım framework altyapısını uzun uzun anlatmak, çıkış hikayesi vb. yazılarla aklınızı karıştırmak değil. Detaylı bilgi almak isteyenler http://www.springsource.com/ adresinden ya da arama motorlarını kullanarak bilgi alabilirler. Arama yaptığınızda siz de anlayacaksınız, tüm sitelerde bu konuya giriş yapılmış. Framework alt yapısı çalışma mantığı anlatılmış fakat elle tutulur bir proje yok. En büyük sorun çalışan uygulama eksikliği. Elimden geldiğince sizlere gerçek şartlarda çalışan uygulamalar göstermeye çalışacağım.

Hangi IDE?

Ben bu örnekte Netbeans 6.8 üzerinden anlatacağım. Bu geliştirme ortamını seçmemin sebebi kolay olması. İçeresinde bir çok gerekli kütüphane hazır olarak geliyor. Olayı kavradıktan sonra Eclipse ile projelerimizi geliştirmeye devam edeceğiz. Buradaki tek amacımız Spring, IDE kaynaklı sorunlarla kafamızı yoramayız.

Ortamın Hazırlanması

Netbeans 6.8 Web EE içeren bir paketini kurmanız yeterli. Ayrıca Java kodlarının derlenmesi için JDK gerekli konumuz Java olmadığı için bundan bahsetme gereği duymuyorum.
File | New
Netbeans geliştirme ortamını açtıktan sonra yeni bir Dynamic Web Application projesi oluşturuyoruz.



Daha sonra dikkat etmeniz gereken tek nokta projemize dahil edeceğimiz kütüphanelerdir. Burada Spring Web MVC 2.5 seçeneğini işaretliyoruz.



Finish diyerek projemizi oluşturuyoruz. Sonra karşınıza şu şekilde bir görüntü çıkmalı.



Şimdi projemizi Run menüsünden ya da F6 kısayol tuşu ile çalıştıralım. Karşınıza aşağıdaki gibi bir ekran çıktıysa merak etmeyin doğru yoldasınız :)



Dur bir dakika! Burada neler oluyor?
Hemen izah edeyim. Az önce bir Spring Web MVC projesi oluşturduk. Netbeans bizim yerimize varsayılan bazı ayarlamaları ve iskelet yapıyı oluşturdu. Bu Netbeans'in özelliği. Sol taraftaki klasör yapısına bakmamız yapıyı anlamada faydalı olacaktır. Web Pages klasörü altında WEB-INF, META-INF klasörleri ve redirect.jsp dosyası var. WEB-INF ve META-INF dışarıdan erişilemeyen (dışarıdan derken, projeyi siteye yüklediğimizde internetten sitemize giren kullanıcıları kastediyorum) özel ayar klasörleridir. Bu klasörlerden bahsetmeden önce ana dizinde bulunan tek dosya olan redirect.jsp ye bakalım. Bildiğimiz gibi Java Dynamic Web projelerinde bütün JSP dosyaları Web Pages altında olurdu ve biz buradaki dosyalara web tarayıcımız vasıtasıyla erişebiliyorduk. Fakat burada yalnız bir dosya var? Öyle ise hemen merakımızı redirect.jsp dosyasına bakarak giderelim.

Buyurun efendim:


Hiçbir şey anlamadım?
Kesinlikle çok saçma! index.htm nerede? Olmayan bir dosyaya yönlendirme mi yapılıyor? Burada bir gariplik var sanki. Evet durum biraz garip ama biraz incelediğimizde ve detaylara dikkat ettiğimizde aslında ne kadar güzel bir yapı olduğunu daha iyi anlayacağız. Burada index.htm dosyasına yönlendirerek aslında index.htm dosyasını açmıyoruz, index adındaki görüntüyü çağırıyoruz.
Görüntü mü? Nasıl yani?
MVC tasarım şablonunun (Model View Controller) ortasındaki View olayından bahsediyoruz. Bu tasarım desenini anlamak biraz sancılı olabilir ama anladıktan sonra hele bir de nimetlerinden faydalandıktan sonra ne kadar güzel bir şey olduğunu siz de anlayacaksınız. Görüntü dediğimiz kavram, önceden hazırlanmış tasarım dosyalarıdır. Herbiri bir controller nesnesine bağlıdır. Onun yetkisi olamadan ilgili görüntüye erişmek mümkün değildir.
İyice karıştı, Controller derken?
Controller sınıflar görüntüleri kullanıcıdan gelen talepler doğrultusunda göstermek ve şekillendirmek adına geliştirilmiştir. Daha detaylı bilgiyi ilerleyen kısımlarda vereceğim.

Tamam ama hâlâ olmayan bir index.htm dosyasını nasıl açtığımızı anlayamadım?

Sır perdesi WEB-INF klasörünü açmamızla aralanacaktır. Bildiğimiz gibi WEB-INF klasörü özel bir ayar klasörü.



xml uzuntılı dosyalar ayarlama için gerekli dosyalar. Sorumuzun cevabı ise jsp klasörü altında gizli. Evet haklısınız, index.jsp :D
Görüntü dosyalarımızı bu klasör altına atmamızın sebebi dış dünyadan soyutlamak. Yalnızca controller nesnesi tarafından erişilmesini sağlamak için yapılmış bir sarmalama mekanizması. Zekice!
Hmm.. Peki ya uzantı?
Sizden de hiçbir şey kaçmıyor :) ama yine de dikkatsizsiniz. Projemizi ilk oluşturduğumuz zamana geri dönelim. Orada Spring Web MVC 2.5 kütüphanesini seçerken Dispatcher Mapping: *.htm şeklinde bir desen girmiştik. İşte bu *.htm şeklinde gelen istekleri .jsp uzantılı görüntülere aktarılmasını sağlıyor. Bu desen çok farklı şekilde olabilir bunları daha sonra inceleyeceğiz. Tüm bu ayarlar WEB-INF altındaki xml uzantılı dosyalarda tanımlanıyor. Bu konuya da daha sonra değineceğim.
Kafam karıştı, böylece bırakıp gidemezsin!
Bu yazımı burada noktalayacağım. Amacım çalışan örneklerle bu konuya değinmekti. Tam olarak hedefime ulaştığım söylenemez, fakat parça parça anlatmak daha faydalı olacak gibi. Konu hakkında yazmaya kaldığım yerden devam edeceğim.
Görüşmek üzere...