Apache Tomcat 7.0.28

Hem web sunucusu olan Apache’yi hem de uygulama sunucusu olan Tomcat ürününü birlikte barındıran Apache Tomcat 7.0.28 versiyonunu 19 Haziran itibariyle piyasaya çıkardı.

Bu versiyonda Web Socket desteği geliştirildi. Annotation incelemeleri hızlandırıldı. Bazı bug’lar giderildi.

Yapılan tüm değişikliklerle ilgili detaylı bilgiye bu linkten ulaşabilirsiniz.

Connection Pool ile Oracle XE’ye Bağlanan Örnek JSF Uygulaması

Bu makalemde Oracle XE veri tabanına bağlanan basit bir JSF uygulaması yazacağım. Veri tabanına bağlanmak için Connection Pool tanımlayacağım. Projede kullandığım teknolojiler şunlar :

–          Eclipse Indigo 3.7

–          Apache Tomcat 7.0

–          Oracle XE 11g

–          JSF 2.0 (Mojarra 2.0.3)

–          PrimeFaces 3.3

Öncelikle yeni bir web projesi oluşturarak JSF 2.0 kullanacağımı belirtiyorum.

Daha sonra web.xml dosyasının oluşturulacağını ve kullanacağım JSF implementasyonunu seçiyorum.

PrimeFaces ve Oracle driver kütüphanelerini WEB-INF – lib dizinine kopyalıyorum.

Bir önceki makalemde belirtmiş olduğum pool tanımlama adımlarını yapıyorum.

Veri tabanındaki Employee tablosuna karşılık bir Java Bean sınıfı yazıyorum.

[codesyntax lang=”java” lines=”no”]

package com.javauzmani.beans;

public class Employee {

	private String firstName;
	private String lastName;
	private String email;
	private String phoneNumber;

	public Employee(String firstName, String lastName, String email, String phoneNumber) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.email = email;
		this.phoneNumber = phoneNumber;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhoneNumber() {
		return phoneNumber;
	}

	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}
}

[/codesyntax]

Sorgu çeken veri tabanı katmanındaki sınıfı yazıyorum. Bu sınıf içerisindeki metot bütün kayıtları getirecek.

[codesyntax lang=”java” lines=”no”]

package com.javauzmani.db;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

import com.javauzmani.beans.Employee;

public class EmployeeDb {

	public List<Employee> getAllEmployees() {
		List<Employee> employees = new ArrayList<Employee>();
		Context envContext = null;
		Connection connection = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			// Sunucuda tanımlanmış datasource'a eriştik
			envContext = (Context) new InitialContext().lookup("java:comp/env");
			// datasouce üzerinden pool'a eriştik
			DataSource pool = (DataSource) envContext.lookup("jdbc/xe");
			// havuzdan bir connection aldık
			connection = pool.getConnection();
			// bağlantı üzerinden statement alıp sorgumuzu yazdık
			stmt = connection.prepareStatement("select first_name,last_name,email,phone_number from employees");
			// sorguyu çalıştırıp dönen sonuçları resultset'te sakladık
			rs = stmt.executeQuery();
			while (rs.next()) {
				Employee e = new Employee(rs.getString("first_name"), rs.getString("last_name"), rs.getString("email"), rs.getString("phone_number"));
				employees.add(e);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				rs.close();
			} catch (SQLException e) {
			} finally {
				try {
					stmt.close();
				} catch (SQLException e) {
				} finally {
					try {
						connection.close();
					} catch (SQLException e) {
					}
				}
			}
		}
		return employees;
	}
}

[/codesyntax]

JSF sayfasından çağıracağım Managed Bean sınıfını tanımlıyorum.

[codesyntax lang=”java” lines=”no”]

package com.javauzmani.managedBeans;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import com.javauzmani.beans.Employee;
import com.javauzmani.db.EmployeeDb;

@ManagedBean
@SessionScoped
public class EmployeeBean implements Serializable {

	private static final long serialVersionUID = 5207408712086947185L;
	private List<Employee> employees = new ArrayList<Employee>();

	public List<Employee> getEmployees() {
		return employees;
	}

	public void setEmployees(List<Employee> customers) {
		this.employees = customers;
	}

	public String getir() {
		employees = new EmployeeDb().getAllEmployees();
		return "employees";
	}
}

[/codesyntax]

En son web sayfalarını tasarlıyorum.

[codesyntax lang=”html4strict” lines=”no”]

<?xml version="1.0" encoding="ISO-8859-9" ?>
<!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">
<h:head>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9" />
	<title>Insert title here</title>
</h:head>
<body>
	<h:form>
		<h4>VERİ TABANINDAN KAYITLARI GETİRMEK İÇİN TIKLAYIN</h4>
		<h:commandButton value="GETİR" action="#{employeeBean.getir}" />
	</h:form>
</body>
</html>

[/codesyntax]

[codesyntax lang=”html4strict” lines=”no”]

<?xml version="1.0" encoding="ISO-8859-9" ?>
<!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:p="http://primefaces.org/ui"
	xmlns:f="http://java.sun.com/jsf/core"
	>
<h:head>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9" />
	<title>Employee Listesi</title>
</h:head>
<body>
	<h:form>
		<p:dataTable value="#{employeeBean.employees}" var="e" bgcolor="silver"
			paginator="true" rows="10"
		>
			<p:column>
				<f:facet name="header">ADI</f:facet>
				#{e.firstName}
			</p:column>
			<p:column>
				<f:facet name="header">SOYADI</f:facet>
				#{e.lastName}
			</p:column>
			<p:column>
				<f:facet name="header">E-POSTA</f:facet>
				#{e.email}
			</p:column>
			<p:column>
				<f:facet name="header">TELEFON</f:facet>
				#{e.phoneNumber}
			</p:column>
		</p:dataTable>
	</h:form>
</body>
</html>

[/codesyntax]

Projemi çalıştırdığımda ekranlar aşağıdaki gibi oluyor.

Tomcat Server üzerine Connection Pool tanımlamak

Çok katmanlı mimaride kod geliştirirken, veri tabanına erişmek için veri tabanı katmanında Connection almak gerekir. Uygulamada kullanılan veri tabanı hangisiyse driver’ı register edilmeli, Connection alınmalı, kullanıldıktan sonra da kapatılmalıdır.

Veri tabanı tarafında Connection açmak kapatmak maliyetli bir iştir. Bu yüzden kod yazarken Connection’ın hangi katmanda açılacağı, aynı bağlantı ile kaç sorgu çalıştırılacağı ve bağlantının nerede kapatılacağı iyi hesaplanmalıdır.

Connection Pool adı verilen yapılar sayesinde veri tabanı tarafında kullanılacak bağlantılar sürekli açık tutulur. Bu sayede her sorgu için tek tek bağlantı açıp kapatma maliyetinden kurtuluruz.

Connection Pool uygulamadan bağımsız bir kavramdır. Dolayısıyla birden fazla uygulama aynı bağlantı havuzunu kullanarak aynı veri tabanına erişebilir. Çok büyük performans kazancı sağlanmış olur.

Connection Pool sunucu üzerinde tanımlanır. Her sunucuda da pool tanımı farklı şekilde yapılır. Çoğu gelişmiş uygulama sunucusunun web arayüzü sayesinde pool tanımları kolay bir şekilde yapılır.

Tomcat Server’da ise bir arayüz olmadığı için pool tanımı XML dosyasına manuel olarak yazdığımız kod ile gerçekleşir.

Ben örnek olarak Oracle XE veri tabanına bağlanmamızı sağlayan DataSource tanımının Tomcat Server üzerinde nasıl yapılacağını göstereceğim.

Öncelikle Tomcat Server’ın kurulu olduğu dizin içerisindeki context.xml dosyası içerisine aşağıdaki gibi bir kod eklenmelidir.

[codesyntax lang=”xml” lines=”no”]

<Resource name="jdbc/xe" auth="Container" type="javax.sql.DataSource"
		removeAbandoned="true" removeAbandonedTimeout="30" maxActive="100"
		maxIdle="30" maxWait="10000" username="hr" password="hr"
		driverClassName="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@localhost:1521:xe" />

[/codesyntax]

Bu kod ile DataSource ismini belirlemiş olduk.

Ayrıca aynı anda kaç bağlantı sürekli açık tutulacak, fazladan açılan bağlantılar ne kadar süre ile saklanacak gibi parametreleri de ayarlamış olduk.

Pool tanımı yapılırken hangi veri tabanına hangi URL ile bağlanacağımızı, driver ismini, veri tabanı kullanıcı adı ve parolasını da belirttik.

context.xml dosyasının yerini bulamadıysanız Eclipse IDE’sinden ulaşabilirsiniz.

Bundan sonra yapmanız gereken web.xml dosyasında pool kullandığımızı belirtmek ve Datasource üzerinden Connection almak.

Uygulamanın kalbi olan konfigurasyon dosyasına (web.xml) aşağıdaki kodu yazıyoruz.

[codesyntax lang=”xml” lines=”no”]

<resource-ref>
	<description>DB Connection Pooling</description>
	<res-ref-name>jdbc/xe</res-ref-name>
	<res-type>javax.sql.DataSource</res-type>
	<res-auth>Container</res-auth>
</resource-ref>

[/codesyntax]

Java kodu ile bağlantıyı da aşağıdaki gibi alıyoruz.

[codesyntax lang=”java” lines=”no”]

Context envContext = (Context) new InitialContext().lookup("java:comp/env");
DataSource dataSource = (DataSource) envContext.lookup("jdbc/xe");
Connection connection = dataSource.getConnection();

[/codesyntax]

Password Strength, p:password

PrimeFaces’da parola bileşeni parola kontrol modulü bulunan tüm uygulamalarda kullanılabilecek gayet başarılı bir bileşen. Bu bileşenle yeni kayıt alacağımız kullanıcıların parola gücünü çok kolay bir şekilde kontrol edebiliyoruz.

Kullanımı da tüm PrimeFaces bileşenlerinde olduğu gibi gayet kolay.

[codesyntax lang=”html4strict” lines=”no”]

<?xml version="1.0" encoding="ISO-8859-9" ?>
<!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:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
	<h:form>
		Parola : <p:password value="#{loginBean.password}"
				feedback="true"
				promptLabel="Parola Giriniz"
				weakLabel="Güçsüz" goodLabel="Orta" strongLabel="Güçlü"
			/>
		<br/>
		<p:commandButton value="GİRİŞ" action="#{loginBean.giris}"/>
	</h:form>
</h:body>
</html>

[/codesyntax]

ManagedBean kodu :

[codesyntax lang=”java” lines=”no”]

package beans;

import javax.faces.bean.ManagedBean;

@ManagedBean
public class LoginBean {

	private String username;
	private String password;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	// şu an için sadece aynı sayfaya yönlendiriyor
	public String giris() {
		return null;
	}
}

[/codesyntax]

Sayfa görüntüleri :