Spring Security + PrimeFaces Yönlendirme Problemi Çözümü

Spring Security, Java EE dünyasında kabul görmüş ve java uygulamaları için -bence- güvenlik için bulunmaz bir nimet. Ayrıntılı bilgiye sitesinden ulaşabilirsiniz.
PrimeFaces da JSF dünyasında kabul gören en başarılı bileşen kütüphanesi, yine bu adresten detaylı bilgiye ulaşabilirsiniz.

JSF 2.2 + Spring 4 + Hibernate 4 + PrimeFaces 5 şeklinde altyapısını kurguladığım projemde fark ettim ki başarılı bir giriş (login) işlemi sonrası sayfa gitmesi gereken URL’e gitmiyor. Spring Security loglarını incelediğimde ise herhangi bir problem olmadan “sendRedirect” ile konfigürasyondaki belirttiğim URL’e gönderiyor. Her şeyin bu kadar mükemmel olduğu yerde nasıl olur da bu çalışmaz diye kafayı sıyırdım tabi ki :)

Spring Security logu aşağıdaki gibi. /login sayfasından istediğim gibi /pages/home sayfasına yönlendirmiş.

[DEBUG] ..access.intercept.FilterSecurityInterceptor - Authorization successful
[DEBUG] ..security.web.FilterChainProxy            - /pages/home.xhtml reached end of additional filter chain; proceeding with original chain
[DEBUG] ..web.access.ExceptionTranslationFilter    - Chain processed normally
[DEBUG] ..web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed

Başladım daha detaylı incelemeye, önce tarayıcı üzerinde gelen-giden akışı izledim.

İstek (Request):

javax.faces.partial.ajax:true
javax.faces.source:loginButton
javax.faces.partial.execute:loginForm
javax.faces.partial.render:loginForm
loginButton:loginButton
loginForm:loginForm
username:test
password:123456
_csrf:49756ca7-38fd-4777-bea8-58fcfe7deb73
javax.faces.ViewState:-3601270081246135757:6121484162719565648

Yanıt (Response):

<?xml version='1.0' encoding='UTF-8'?>
<partial-response id="j_id1"><changes><update id="j_id1:javax.faces.ViewState:0"><![CDATA[-6140875972550706628:-2367790204853062502]]></update></changes></partial-response>

Bunları görünce tabi ki “Aman Tanrım didim”, neden mi? :)
Çünkü gelen yanıtta “redirect-url” yok! Sadece “update” var! Yani ajax işinde hata yapmışız (javax.faces.partial.ajax:true) ve bunu aşmak için önümüzde iki yol var;

  1. Primefaces commandButton özelliklerinde ajax=”false” demek
  2. Primefaces butonu yerine klasik JSF butonu kullanmak

Kullandığım buton

<p:commandButton value="Giriş Yap" />

1. yol

<p:commandButton value="Giriş Yap" ajax="false"/>

2. yol (primefaces butonunun css’inden faydalanamazsınız, elle eklemeniz lazım)

<h:commandButton value="Giriş Yap" />

Sonuç olarak bu kadar basit görünse de tarayıcı üzerindeki trafiği izlemeden ben anlayamadım. Bu arada tüm tarayıcılarda neredeyse standart haline geldi, “Developer Tools” deniliyor genelde ve F12 tuşu ile açabiliyorsunuz, bilmeyenler olabilir diye bahsedeyim dedim.

Bunların dışında Spring Security’nin “sendRedirect” yaptığı yeri ezerek (override) de bu işi yapabilirdik ama daha maliyetli olurdu. Nasıl yapılabileceği şuradaki cevapta üstad BalusC tarafından verilmiş :)

Sorunun temeline de şu kaynaktan bakılabilir.

Application Servers kategorisine gönderildi | Yorum bırakın

JSF 2 + PrimeFaces

PrimeFaces, JSF 2 için yazılmış bileşen kütüphanelerinin en başında gelmektedir. Şu an itibariyle de NetBeans geliştirme ortamında hazır gelen tek bileşen kütüphanesidir. Gelişmiş bir çok bileşenini ve detaylarını demo sayfalarında bulabilirsiniz.

Bu yazıya başlamadan önce…
Daha önce yazmış olduğum şu yazıları, bu makaleye başlamadan önce okumanızı tavsiye ederim.

  1. JSF Life Cycle
  2. JSF Model-View-Controller
  3. JSF 2′ye Giriş

Konular hakkında bilgili olanlar tabi ki okumasına gerek yok, lakin JSF 2′ye giriş yazısında oluşturduğumuz geliştirme ortamı üzerinden bu yazıya devam edeceğim için, en azından ona bakmanızda fayda var.

PrimeFaces ile Güçlenmek
JSF 2 projemizi PrimeFaces ile güçlendirmek sadece iki adımdan oluşmaktadır.

  1. PrimeFaces indirme sayfasından en son kararlı sürümü indirmek ve projenin kütüphaneleri arasına eklemek
  2. xhtml sayfalarının başındaki xmlns tanımları arasına aşağıdaki satırı eklemek.
  3. xmlns:p="http://primefaces.prime.com.tr/ui"

Evet, sadece bu kadar! Bundan sonra sayfalarımız içinde Aşağıda, bu iki adımı da gerçekleştirmiş jsf2-helloworld projesinin ekran görüntüsünü görebiliriz.

Görüldüğü üzere index.xhtml sayfası içerisine bileşenini eklemiş bulunmaktayız. Projeyi çalıştırıp index.jsf sayfasını çalıştırdığımızda aşağıdaki gibi bir görümüne sahip oluruz.

Bir sonraki yazıda bu JSF 2 + PrimeFaces uygulamamızı Ajax kullanarak geliştireceğiz.

Kolay gelsin.

Java, JSF kategorisine gönderildi | , , , ile etiketlendi | 5 yorum

JavaServer Faces 2 (JSF 2)

JavaServer Faces (JSF), Java Komitesi tarafından standart web teknolojisi olarak kabul edilmiştir. Java ile web programlama yapmak isteyen bir kişinin mutlaka öğrenmesi tavsiye edilir. Ayrıntılı bilgiye http://javaserverfaces.java.net/ adresinden erişebilirsiniz.

JSF, Model-View-Controller (MVC) tabanlı olduğundan Java sınıflarımız ile görsel sayfalarımız yani önyüzümüz farklı farklı katmanlarda bulunmaktadır. Bu konuyu detaylı bir şekilde şu sayfada anlatmıştım.

Şimdi JSF 2 ile ilk uygulamamızı yapalım. Bize aşağıdaki malzemeler lazım daha doğrusu ben bunları kullanacağım;

Tomcat
Eclipse başlatıp yeni bir çalışma alanı (workspace) açalım. İlk olarak “Server”ı tanıtalım. Server tabında sağ tıklayarak New > Server yolunu takip ettikten sonra Tomcat’in yerini aşağıdaki gibi gösterebilirsiniz.

Proje Oluşturma
Şimdi “Package Explorer” ya da “Project Explorer” görünümünde New > Dynamic Web Project yolu ile aşağıdaki gibi projeyi oluşturuyoruz. Önce proje ismi gibi alanları dolduruyoruz.

Sonra ileri ve tekrar ileri diyerek aşağıdaki gibi “web.xml” dosyasını oluşturmasını sağlayıp “finish” butonuna basarız.

JSF 2 için Gerekli Jarlar
JSF 2 uygulamamızın çalışması için yapmamız gereken bir kaç adım var, ilk olarak en başta belirttiğimiz 2 adet jar dosyasını WEB-INF/lib dizini altına kopyalayalım, projemizin görünümü aşağıdaki gibi olmalı.

web.xml Ayarları
JSF 2 uygulamamızın server tarafından yorumlanabilmesi için web.xml içine şu satırları eklememiz lazım.

        <!-- Faces Servlet -->
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup> 1 </load-on-startup>
	</servlet>

	<!-- Faces Servlet Mapping -->
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.jsf</url-pattern>
	</servlet-mapping>

Bu satırları ekledikten sonra web.xml dosyasının görünümü aşağıdaki gibi olacaktır.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<display-name>jsf2-helloworld</display-name>

	<!-- Faces Servlet -->
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup> 1 </load-on-startup>
	</servlet>

	<!-- Faces Servlet Mapping -->
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.jsf</url-pattern>
	</servlet-mapping>

	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
	</welcome-file-list>
</web-app>

xhtml Sayfası Oluşturmak
Artık tüm altyapı hazırlıklarımız tamam, sıra geldi bir sayfa oluşturup çalıştırmaya. WebContent dizini altına index.xhtml adında bir dosya oluşturup aşağıdaki gibi düzenliyoruz.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>jsf2-helloworld</title>
</h:head>
<h:body>

	Merhaba JSF 2
	
</h:body>
</html>

Projenin Çalıştırılması
Tomcat’in menüsünden Add and Remove aracılığı ile projemizi Tomcat altına ekliyoruz.

Daha sonra Tomcat’i başlatıyoruz. Herhangi bir port değişikliği yapmadıysanız http://localhost:8080/jsf2-helloworld/index.jsf bağlantısına gidince karşımıza aşağıdaki ekran gelir.

En saf haliyle bir JSF 2 uygulamasına sahibiz. Bundan sonraki derste bu uygulamamıza, PrimeFaces component suite eklemesi yapacağız. Uygulamayı sade halinden PrimeFaces’ın sağladığı bileşenlerle zenginleştireceğiz.

Kolay gelsin.

Java, JSF kategorisine gönderildi | , , , ile etiketlendi | 5 yorum

XML’deki Listeyi Okuyarak Nesnelere Çevirme

XStream kütüphanesinden buradaki yazıda bahsetmiştim. Java’dan XML’e, XML’den Java’ya dönüşüm yapmamıza yardımcı oluyordu. Yalnız bir konuyu es geçtiğimi farkettim, ya nesne yerine nesneler olsa o zaman nasıl bir çıktı alacağız? XML’de liste halinde bir sürü nesne olsa o zaman nasıl Java’ya çevireceğiz? Bu yazıda bu konuları aydınlatmaya çalışacağım, fakat ilk yazının mutlaka okunması gerek, çünkü oradaki “Ders” ve “Ogretmen” sınıflarını kullanacağım.

Tek bir “Ders” nesnesinin XML çıktısını oluşturmak çok kolaydı ve aşağıdaki gibi bir sonuç veriyordu.

<Ders>
  <id>1</id>
  <ad>Software Engineering</ad>
  <ogretmen>
    <ad>Yasin</ad>
    <soyad>Kenar</soyad>
  </ogretmen>
</Ders>

Peki ama birden fazla “Ders” nesnesi olsa ne olacak, çıktı nasıl şekillenecek ve öncesinde biz nasıl ürettireceğiz :) Aşağıda kodda, iki adet “Ogretmen” nesnesi üretip bunları kullanarak da üç adet “Ders” nesnesi oluşturacağım (15 ve 19. satırlar arası). Sınıfların özelliklerine yukarıda bağlantısını verdiğim sayfadan bakabilirsiniz.

Sonra bu oluşturduğum nesneleri bir listeye ekleyeceğim (21 ve 24. satırlar arası).

Son olarak da XStream nesnemin toXML() metoduna “listemi” vereceğim. Evet önceki örnekte direk “Ders” nesnemi vermiştim, bu sefer listeyi veriyorum (26 ve 28. satırlar arası).

package org.sukru.xstream.test;

import java.util.ArrayList;
import java.util.List;

import org.sukru.xstream.entity.Ders;
import org.sukru.xstream.entity.Ogretmen;

import com.thoughtworks.xstream.XStream;

public class XStreamListTest {

	public static void main(String[] args) {
		
		Ogretmen o1 = new Ogretmen("Yunus Emre", "Aslan");
		Ogretmen o2 = new Ogretmen("Yasin", "Kenar");
		Ders d1 = new Ders(1L, "Türkçe", o1);
		Ders d2 = new Ders(2L, "Arapça", o2);
		Ders d3 = new Ders(3L, "Farsça", o2);
		
		List<Ders> dersList = new ArrayList<Ders>();
		dersList.add(d1);
		dersList.add(d2);
		dersList.add(d3);
		
		XStream xstream = new XStream();
		xstream.alias("Ders", Ders.class);
		String xml = xstream.toXML(dersList);
		System.out.println(xml);
	}
}

En son olarak da çıktıyı aldığımızda XML aşağıdaki gibi oluyor.

<list>
  <Ders>
    <id>1</id>
    <ad>Türkçe</ad>
    <ogretmen>
      <ad>Yunus Emre</ad>
      <soyad>Aslan</soyad>
    </ogretmen>
  </Ders>
  <Ders>
    <id>2</id>
    <ad>Arapça</ad>
    <ogretmen>
      <ad>Yasin</ad>
      <soyad>Kenar</soyad>
    </ogretmen>
  </Ders>
  <Ders>
    <id>3</id>
    <ad>Farsça</ad>
    <ogretmen reference="../../Ders[2]/ogretmen"/>
  </Ders>
</list>

Farkları neler? Birden fazla ders nesnesi var

<list>
</list>

arasında yer alıyor ve id bilgisi 3 olan “Ders” nesnesinin “ogretmen” bilgisi

<ogretmen reference="../../Ders[2]/ogretmen"/>

şeklinde 2. sıradaki “Ders”in “ogretmen” bilgisi ile aynı olarak gösteriliyor.

Şimdi asıl konumuza gelelim, bu xml çıktısını alıp yeni bir xml dosyası oluşturalım, adını da “dersler.xml” olarak verip projemizin altında oluşturacağımız “files” dizini altında oluşturalım. Aşağıda projenin yeni yapısını görebilirsiniz.

Bu xml dosyasını okuyarak XStream in fromXML() metodu ile nesnemize atayacağız. Adım adım işlemlerimizi yazıp gerçekleyelim.

  1. Dosya ismini al. (“files/dersler.xml”)
  2. XStream nesnesi oluştur ve alias tanımla. (XML de nesne “Ders” olarak tutulduğu için alias tanımlamalıyız. Paket ismi ile olsaydı gerek kalmazdı. )
  3. BufferedReader nesnesine bu dosyayı okuyarak at.
  4. XStream nesnesi üzerinden fromXML metoduna BufferedReader nesnesini ver, listeyi alsın.
  5. Listeyi dönerek nesneyi aldığımızı gösterelim.

Kodunu yazarsak;

package org.sukru.xstream.test;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.List;

import org.sukru.xstream.entity.Ders;

import com.thoughtworks.xstream.XStream;

public class XStreamReadingListTest {

	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		String file = "files/dersler.xml";
		BufferedReader reader = null;
		XStream xstream = new XStream();
		xstream.alias("Ders", Ders.class);
		try {
			reader = new BufferedReader(new FileReader(file));

		} catch (FileNotFoundException e) {
			System.out.println("[" + file + "] adresinde belirtilen dosya bulunamadı!");
			e.printStackTrace();
		}

		StringBuffer sb = new StringBuffer();

		List<Ders> dersList = (List<Ders>) xstream.fromXML(reader);
		for (Ders ders : dersList) {
			sb.append(ders.getId()).append(" - ").append(ders.getAd()).append("\t").append(ders.getOgretmen().getAd()).append("\n");
		}		
		System.out.println(sb);
	}
}

En sonunda ekrana bastırmıştık, çıktıyı da verelim :)

1 - Türkçe Yunus Emre
2 - Arapça Yasin
3 - Farsça Yasin

Bu kodları kendi ortamınızda derleyip adım adım debug yaparsanız, çok daha iyi anlayabilirsiniz.

Kolay gelsin.

Java, XML kategorisine gönderildi | , , , , ile etiketlendi | 6 yorum

Java Package

Java Package (paket) kavramı Java sınıflarını düzenli tertipli biçimde biraraya getirmek, organize etmek için kullanılır. Aynı kategorideki ya da benzer görevdeki sınıflar biraraya getirilerek mantıksal bir bütünlük sağlanır. Bilgisayarınızdaki klasörler gibi düşünebilirsiniz; müziklerim şurada olsun, resimlerimi şuraya koyayım gibi…

  • “package” bir Java sınıfına ait eşsiz bir ad uzayı oluşturur. Örnek olarak String sınıfı java.lang paketi altında tektir, bulunduğu paket de tektir.
  • Aynı paketteki sınıflar birbirlerinin “package-access members” yani paket seviyesinde erişim üyeleri olurlar. Bu kavram şu an havada kalabilir, başka bir yazıda “erişim” üzerine detaylı inceleme yaparız, orada daha iyi anlaşılır.

İsimlendirme Standartı
Çoğu yazılım standartı gibi, bu da zorunlu olmayan ama bu şekil kullanılırsa insanların daha rahat anlayabilecekleri ve anlaşabilecekleri bir düzen olarak karşımıza çıkmaktadır. Örnek olarak ben şu an i2i systems isimli şirkette çalışıyorum ve “EasyProv” adında ticari (commercial) bir uygulama yazıyorum, uygulama üzerindeki sık kullandığım araçları (utilities) bir paket altında toplamak istiyorum;

 
package com.i2i.easyprov.util;

Tekrar okursak şu bilgileri ediniyoruz;

  1. com – Ticari bir paket
  2. i2i – i2i şirketi yazmış
  3. easyprov – easyprov projesine ait
  4. util – util (utilities) yani araçlar burada bulunuyor

Kısacası bu paket altında neler bulabileceğim önceden görünüyor :)

Java Temel Paketlerinden bazıları…

  • java.lang — dilin işlevselliği ve temel tiplerin bulunduğu paket, String, Integer gibi…
  • java.util — collection veri yapılarının sınıfları
  • java.io — dosya işlemleri
  • java.math — matematiksel işlemler
  • java.net — ağ operasyonları, socket programlama vb…
  • java.security — anahtar üretme, şifreleme, çözümleme…
  • java.sql —veritabanlarına erişim için Java Database Connectivity (JDBC)
  • java.awt — masaüstü uygulamaları için görsel arayüz bileşen paketi
  • javax.swing — awt gibi ama platform bağımsız arayüz bileşen paketi
  • java.applet — applet geliştirmek için kullanılan sınıfların bulunduğu paket

Umarım faydalı olmuştur :) en sevmediğiniz paket “default package” olsun.
Kolay gelsin.

Kaynaklar

  1. http://download.oracle.com/javase/tutorial/java/concepts/package.html
  2. http://en.wikipedia.org/wiki/Java_package
Java kategorisine gönderildi | Yorum bırakın

Introduction to Exception Handling – Hata Yakalamaya Giriş

Java’da “exceptions” kavramı hataları yakalamak ve istisnai durumlar için kullanılır. Güçlü bir yazılım için çok gereklidir fakat çoğu zaman gözardı edilmektedir. Biz gözardı etmeyelim.

“Exception”, programın çalışması sırasında normal akışı kesen bir olaydır. Aşağıdaki resimde “main” metodundan sırasıyla aşağıdan yukarı bir akış görüyoruz ve son adımda bir hata olduğunu anlıyoruz. Hata aldığı yerden itibaren kod, hatayı yakalayabilecek kısmı (exception handler) aramaya başlıyor, bu sefer ters sırada. Hata yakalama mekanızmasını (handler) bulunca hatayı uygun yakalayıcıya geçiyor.

Bu işlemlere hata yakalama (catch the exception) diyoruz.

Hata yakalama işlemi;

  • try kod bloğu içinde yakalanarak ya da
  • throws ifadesi ile metodun başında belirlenerek yapılabilir.

Hataların 3 tipi vardır;

  1. Checked Exception
  2. Error
  3. Runtime Exception

1. Checked Exception
Örnek olarak java.io.FileReader sınıfından bir nesne ile dosya okuma işlemi yapıyorsunuz, dosya ismi veriyorsunuz ve dosyayı bulamayarak java.io.FileNotFoundException hatası fırlatıyor. İyi yazılmış bir programda bunu try-catch bloğu içinde yakalarsınız ve hatayı kullanıcıya bildirir, dosya ismini düzeltmesini sağlarsınız.

“Error” ya da “Runtime Exception” haricindeki bütün durumlar “Checked Exception” olur.

2. Error
Sizin uygulamanız dışındaki ekstra uygulamalardan kaynaklanan durumlardır. Örnek olarak, dosya okumak istiyorsunuz ama daha dosya sisteminize -mesela diske- erişilemiyor, işte burada “Error” tipinde bir durum oluşur, uygulama java.io.IOError. hatası fırlatır.

3. Runtime Exception
Uygulamanızın çalışma zamanında oluşan durumdur. Uygulamanın kendisinden kaynaklanır, programın bug ıdır, mantık hatasıdır ya da API’nın yanlış kullanımından kaynaklanır :) He ben niye güldüm, herkes gibi ben de yaptım ve genellikle NullPointerException aldım ondan :)

Şimdi daha açık olması bakımından örneklersek, dosya okumak istiyorsunuz ama dosya adını vermediniz, ee ne olacak çat NullPointerException alacaksın. Yani çalışma zamanında uygulama patlamış (!) – genelde böyle derler- olacak.

Bu arada “Error” ve “Runtime Exception” kavramlarına topluca “Unchecked Exceptions” da denilir.

Giriş için daha doğrusu zihninizde yer edinmesi, karşılık bulması için bu kadar bilginin yeterli olduğunu düşünüyorum. Bu konuda yazacağım bir sonraki yazıda bol bol kod yazacağız :)

Kolay gelsin.

Kaynaklar

  1. http://download.oracle.com/javase/tutorial/essential/exceptions/
  2. http://tutorials.jenkov.com/java-exception-handling/index.html
Exceptions, Java kategorisine gönderildi | , ile etiketlendi | Yorum bırakın

Generic Types

Programlamada bazen öyle olur ki bazı değerlerin tipleri önceden kestirilemez. Siz gelecek değerin Integer olmasını beklerken, bir bakmışsınız String gelmiş, uygulamanız java.lang.ClassCastException hatası almış, java.lang.String cannot be cast to java.lang.Integer diyerek gelen String değerin Integer’a dönüştürülememiş olur.

İşte bu durumda Generic Types (Genel Tipler) kavramı karşımıza çıkar.

Şimdi yukarıda bahsettiğim olayı göstermek açısından hata ile karşılaştığımız bir örneği gösteriyorum. Object tipinde bir değişkeni olan Box isimli bir sınıf var.

package org.sukru.classic;

public class Box {

	private Object object;

	public void add(Object object) {
		this.object = object;
	}

	public Object get() {
		return object;
	}
}

add() metoduna gönderdiğimiz değişkenin tipi ne olursa kabul edecek de, get() metodunda mecburen “cast” etmemiz gerekecek.

package org.sukru.classic;

import org.sukru.classic.Box;

public class BoxTest {

	public static void main(String[] args) {
        Box integerBox = new Box();
        integerBox.add(new Integer(10)); // Ya burada String ekleseydim?
        Integer someInteger = (Integer) integerBox.get();
        System.out.println(someInteger);
	}
}

Evet, bu kodları çalıştırdığımızda buraya kadar bir sıkıntı yok ama kod içine de not düştüğüm gibi ya orada integerBox.add("10"); şeklinde String olarak parametre verseydim işte o zaman ilk bahsettiğim java.lang.ClassCastException hatasını alırız.

Çözüme gelirsek, Box sınıfını ifadesiyle aşağıdaki gibi generic type olduğunu belirtirsek, ne gelirse gelsin :) bu arada sınıf isimleri aynı olmasına rağmen farklı bir paket altında çalıştığıma dikkat edin.

package org.sukru.generics;

public class Box<T> {
	private T t; // T burada "Type" anlamına gelir.

	public void add(T t) {
		this.t = t;
	}

	public T get() {
		return t;
	}
}

Yukarıdaki

Box<T>

ifadesindeki T’nin anlamını biraz açarsak “Type” anlamına geldiğini söyleyebiliriz, yani bu sınıftan herhangi bir tipte nesne tanımlanabilir.

Box<Integer> integerBox = new Box<Integer>();

da olabilir

Box<String> integerBox = new Box<String>(); 

da ya herhangi başka bir tip, primitive tipler hariç!

Şimdi buradan hareketle Integer tipinde bir Box nesnesi üreterek üzerinden gidilecek.

package org.sukru.generics;

public class BoxTest {

	public static void main(String[] args) {
		Box<Integer> integerBox = new Box<Integer>();
		integerBox.add(new Integer(10));
		Integer someInteger = integerBox.get(); // cast'e gerek yok!
		System.out.println(someInteger);
	}
}

Önceki örnekte Integer tipine dönüştürmeye (cast) ihtiyaç vardı, bu örnekte gerek yok. Ayrıca daha güzeli, geliştirme ortamları (IDE) siz farkında olmadan add() metoduna Integer’dan farklı bir tip göndermeye kalkarsanız, sizi daha çalıştırmadan uyarır :) Bence en önemlisi bu :)

Bu arada Java 7 ile beraber nesne üretme ifadesi kısalarak

Box<Integer> integerBox = new Box<>();

şeklinde olacakmış, yani diamond operator denilen kısıma tekrardan tip belirtmeye gerek kalmayacakmış.

Aklınızda şu soru belirmiş olabilir, bu “T” de neyin nesi idi, ben başka birşey kullanabilir miyim. İşte burada da Java Naming Convention dediğimiz Java İsimlendirme Standartları devreye giriyor.

  • E – Element (genellikle Java Collection Framework da kullanılıyor)
  • K – Key
  • N – Number
  • T – Type
  • V – Value
  • S,U,V vb. (eğer 2., 3., 4. tipler gerekirse de bu harfler seçiliyor)

Standartlar olmasaydı birbirlerinden ayırt etmek zor olacaktı, yani gözünü seveyim standartların :)
Umarım konuyu anlamak açısından faydalı olmuştur.

Kolay gelsin.

Not: Anlaşılırlığı artırmak bakımından http://download.oracle.com/javase/tutorial/java/generics/index.html adresindeki örnekler kullanılmıştır.

Generics, Java kategorisine gönderildi | , , ile etiketlendi | 1 yorum

JSF Model-View-Controller (MVC)

Yeni nesil Internet uygulamalarında karşımıza çıkan ilk kavramlardan biri, MVC açılımı Model-View-Controller. JSF de kendine örnek olarak MVC yapısını baz almaktadır.

  1. Model – Java sınıflarımız
  2. View – Görsel Sayfalarımız, önyüzümüz
  3. Controller – Servlet (Faces Servlet) olarak görülebilir.

JSF Referans kitabında konu ile alakalı şu resim olayı betimliyor.

Resimdeki örnek projeye göre daha da açarsak; Model katmanında Java Beans bulunurken (User.java, Account.java, Item.java, ShoppingCart.java, vb…), View katmanında xhtml sayfalarımız (showUser.xhtml, purchase.xhtml, editUser.xhtml vb…) bulunur ve bu sayfalar son kullanıcının gördüğü görsel sayfalardır. Tabi temelde işleri yöneten de Controller dediğimiz Faces Servlettir. Faces Servlet kavramını çok açmıyorum, JSF’in derinlerine başka bir yazıda inip inceleriz.

Sözün özü, kurumsal uygulamalarda (Java için JavaEE) katmanlar birbirinden ayrılmıştır. Sunum katmanı (View) son kullanıcıya yönelik, arka plana iş veren, görsel bir pozisyon üstlenirken, arka plandaki iş mantığını yapan (Model) ayrı bir katman olarak bulunmakta ve bunları da yöneten, kontrol eden (Controller) bir başka katman bulunmaktadır.

Yazılım dili bağımsız bir kavram olan MVC’yi, sanıyorum ki Java bilsin bilmesin herkes temelde bu gösterimle anlayabilir. :) Anlamayan iletişime geçsin.

Kolay gelsin.

Java, JSF kategorisine gönderildi | , , , , ile etiketlendi | 4 yorum