Bu yazıda JSP teknolojisinin ne olduğunu anlatıp basit örnekler ile JSPyi uygulamada göreceğiz. Bu yazıya başlamadan önce Örnek Servlet yazısını okumalısınız.
JSP Nedir?
JSPnin açılımı Java Server Pages‘dir. JSP teknolojisi, hem durağan (statik) hem de dinamik parçaları olan web içeriğini kolayca yaratmanızı sağlar. JSP, Servlet teknolojisinin tüm özelliklerini barındırırken aynı zamanda web içeriği yaratmanın daha doğal ve kolay yolunu sunar.
JSP teknolojisinin temel özellikleri şunlardır:
- JSP sayfaları yaratmak için bir dil sunar. JSP sayfaları text tabanlı, HTML benzeri sayfalardır. Durağan (statik) veya dinamik web sayfaları oluşturmayı kolaylaştırır.
- Sunucu tarafındaki nesnelere erişmek için bir
expression language
sunar. - JSPye kendi özelliklerinizi eklemeniz için yollar sunar (örneğin custom tags)
Bir JSP Örneği
Bir JSP sayfası yazmak için, servletlerde olduğu gibi, önce bir Dynamic Web Project oluşturmalıyız. Yeni bir proje oluşturmak yerine bir önceki yazıda oluşturduğumuz projeyi kullanalım.
Projedeki WEBContent
klasörü içinde merhaba.jsp
adlı bir dosya oluşturacağız. Bunun için WEBContent
klasörüne sağ tıklayıp New -> JSP File
seçeneğini seçelim.
Oluşan dosya içeriği aşağıdaki gibi olacaktır:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
</body>
</html>
body
tagleri arasına Merhaba dünya yazabiliriz. merhaba.jsp
dosyasını aşağıdaki gibi olacak biçimde güncelleyelim:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Bir JSP Sayfasından Merhaba Dünya</title>
</head>
<body>
Merhaba Dünya
</body>
</html>
Dikkat ederseniz şablondaki <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
doctype tanımını <!DOCTYPE html>
ile değiştirdik. Böylece tarayıcılara sayfamızın HTML5 kullandığını söylemiş oluruz. Örneklerde bazen sadelik için doctype tanımı hiç konmayabilir de, pratikte tarayıcılar için bu bir fark yaratmaz.
Daha sonra uygulamayı çalıştıralım. Bunun için proje adına sağ tıklayıp Run as -> Run on server
seçeneğini seçeriz.
http://localhost:8080/MerhabaDunya/merhaba.jsp adresini açtığınızda sayfanın çıktısını görebilirsiniz.
Dinamik JSP Sayfası
Şimdiye kadar yaptığımız sayfalar (bir önceki örnekteki servlet ve şimdiki JSP) durağan sayfalardı. Yani kullanıcı her istek yaptığında aynı içerik ile karşılaşıyordu. Artık sayfalarımıza biraz dinamiklik katalım, yani her açıldığında aynı içeriği göstermesin. Bunun ilk akla gelen örneği kullanıcıya saati gösteren bir web sayfasıdır.
Bunun için WEBContent
klasörü içinde saatKac.jsp
adlı bir dosya oluşturacağız. Eclipse’in eklediği JSP şablonunu aşağıdaki gibi güncelleyin:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.time.LocalTime" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Saat Kaç?</title>
</head>
<body>
<h1>JSP Örneği</h1>
Saat :<%= LocalTime.now() %>
</body>
</html>
Burada <%@ page import="java.time.LocalTime" %>
satırı dikkatinizi çekmeli. Bu bir Include directive
. Java sınıflarında olduğu gibi kullandığımız kütüphaneleri include etmeye yarar. Direktifleri birazdan daha ayrıntılı inceleyeceğiz.
http://localhost:8080/MerhabaDunya/saatKac.jsp adresini açınca sunucuzunun saatini görebilirsiniz. Sayfayı her yenilediğinizde saatin (en azından saniyenin) değiştiğini göreceksiniz. Çünkü her istekte HTML sayfası yeniden oluşturuluyor ve JSP sayfanızdaki Java kodları yeniden çalıştırılıyor.
JSP Nasıl Çalışır?
JSP sayfaları aslında birer Servlet
tir. Detaylandırmak gerekirse, JSP sayfaları sunucu tarafından önce bir Servlet sınıfına dönüştürülür (Translation) ve daha sonra derlenir (Compilation).
Bir request bir JSP sayfasına iletildiği zaman (url mapping olunca), sunucu önce ilgili JSPnin servlet sınıfı ile JSP sayfasının kendisini karşılaştırır. Eğer JSP sayfası daha yeniyse veya ilgili JSP için henüz bir Servlet oluşturulmamışsa JSPyi yeniden Servlete dönüştürür ve derler. Daha sonra gelen requesti bu Servlet sınıfına iletir. Bundan sonraki aşamalar önceden gördüğümüz Servletlerle aynıdır.
JSP Sayfalarının Servlet'e Dönüştürülmesi
Eclipse’in kullandığı workspace klasörü workspace
olsun. O zaman otomatik oluşturulan Servletleri
workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/work/Catalina/localhost/MerhabaDunya/org/apache/jsp
altında bulabilirsiniz. (Sizin için tmp0
klasörü farklı adlarda olabilir. tmp1
, tmp2
gibi…)
Örneğin saatKac.jsp
dosyasının Servlet’e dönüştürülmüş hali, yani saatKac_jsp.java
dosyası şöyledir:
public final class saatKac_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
// ...
// sadelik için çıkarıldı
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException {
// ...
// sadelik için çıkarıldı
try {
response.setContentType("text/html; charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\n");
out.write("\n");
out.write("\n");
out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
out.write("<html>\n");
out.write("<head>\n");
out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
out.write("<title>Saat Kaç?</title>\n");
out.write("</head>\n");
out.write("<body>\n");
out.write("\n");
out.write(" <h1>JSP Örneği</h1>\n");
out.write("\n");
out.write(" Saat :");
out.print( LocalTime.now() );
out.write("\n");
out.write(" \n");
out.write("</body>\n");
out.write("</html>");
} catch (java.lang.Throwable t) {
// ...
// sadelik için çıkarıldı
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
Otomatik oluşturulan saatKac_jsp
sınıfı HttpJspBase
sınıfını extend ediyor. Tomcat 8’in APIsine bakacak olursanız aşağıdaki gibi bir sınıf hiyerarşisi görürsünüz.
java.lang.Object
└╴javax.servlet.GenericServlet
└╴javax.servlet.http.HttpServlet
└╴org.apache.jasper.runtime.HttpJspBase
Otomatik oluşturulan sınıfın extend ettiği HttpJspBase
sınıfı da zaten HttpServlet
ten extend edilmiş. Yani sonuçta saatKac_jsp
sınıfı da bir Servlet.
Daha sonra sunucu saatKac_jsp.java
dosyasını derleyerek saatKac_jsp.class
dosyasını oluşturur ve artık bu dosyayı çalıştırır.
JSP Elemanları
Directive
Directive | Açıklama |
---|---|
<%@ page … %> | Sayfaya özgü özellikleri tanımlar. Örneğin bir kütüphane import eder, session a bilgi koyar gibi... |
<%@ include … %> | Mevcut JSP sayfasına bir başka sayfa eklemeye yarar. |
<%@ taglib … %> | Sayfada kullanılacak bir tag kütüphanesi tanımlar. |
Scriptlet
JSP içine yazılan Java kodlarıdır. Bir java dosyası içine yazılan herhangi bir Java kodunu yazabilirsiniz. Örneğin ipGoster.jsp
sayfası ekleyip içeriğini aşağıdaki gibi değiştirseniz bir scripletin çıktısını görebilirsiniz.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>IPniz</title>
</head>
<body>
<% out.println("IP adresiniz: " + request.getRemoteAddr()); %>
</body>
</html>
Action Tag
JSP sayfasının request processing
aşamasındaki davranışını etkilemek için kullanılır. Kullanımı
<jsp:action_adı attribute="deger" />
biçimindedir. <jsp:include>
dışındakileri pek kullanmayacağız.
Expressions
İçine yazılan _expression_ı çalıştırıp, çıktısını String
e çevirip, ekrana yazan elemanlardır. saatKac.jsp
sayfasında da kullanmıştık. LocalTime.now()
_expression_ının değerini String
olarak ekrana yazdırmıştı.
<%= LocalTime.now() %>
Biçiminde kullanılır.
Declaration
JSP sayfasının tamamında geçerli olacak değişken tanımlamayı sağlayan elemanlardır. declarationOrnegi.jsp
diye bir JSP sayfasının bodysine şunları yazalım:
<body>
<%! LocalTime time1 = LocalTime.now(); %>
<% LocalTime time2 = LocalTime.now(); %>
<p><%= "Time 1: " + time1 %></p>
<p><%= "Time 2: " + time2 %></p>
</body>
http://localhost:8080/MerhabaDunya/declarationOrnegi.jsp adresini açıp birkaç kez yenilerseniz, Time1in değişmediğini ancak Time2nin her yenilemede değiştiğini göreceksiniz.
Çünkü scriptlet (<% ... %>
) içinde yapılan değişken tanımları oluşturulan servlet sınıfının service methodu içinde tanımlanır, yani yerel değişken olur.
Ancak declaration (<%! ... %>
) içinde yapılan değişken tanımları oluşturulan servlet sınıfının içinde bir field olarak tanımlanır.
Servletlerden hatırlayacağımız üzere her request handle edilirken service metodu yeniden çağırılır. Ancak JSP sayfasından oluşturulan bir servlet sınıfı JSP değişmedikçe yeniden oluşturulmaz. Aşağıda sunucu tarafından oluşturulan servlet kodunu incelerseniz neler olduğunu daha net göreceksiniz:
public final class declarationOrnegi_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
LocalTime time1 = LocalTime.now();
// ... sadelik için çıkarıldı
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
try {
// ... sadelik için çıkarıldı
out.write('\n');
out.write(' ');
LocalTime time2 = LocalTime.now();
out.write("\n");
out.write("\t\n");
out.write("\t<p>");
out.print( "Time 1: " + time1 );
out.write("</p>\n");
out.write("\t<p>");
out.print( "Time 2: " + time2 );
// ... sadelik için çıkarıldı
JSP Sayfasındaki Öntanımlı Nesneler
Nesneler | Açıklama |
---|---|
request | Servletlerde de gördüğümüz HttpServletRequest nesnesi. |
response | Servletlerde de gördüğümüz HttpServletResponse nesnesi. |
out | Doğrudan kullanıcıya yollanan response a yazmaya yarayan PrintWriter nesnesi. |
session | Mevcut request ile ilişkilendirilmiş HttpSession nesnesi. |
application | Mevcut uygulama ile ilişkilendirilmiş application context ServletContext nesnesi. |
config | Mevcut sayfa ile ilişkilendirilmiş ServletConfig nesnesi. |
pageContext | Tüm öntanımlı nesneleri otomatik olarak içerir(request, session vb.). |
page | JSPnin dönüştürüldüğü Servlet instanceı için this keywordüne eşdeğerdir, servletin kendisini belirtir. |
exception | Exception handling ve hata mesajı göstermek için kullanılan Exception nesnesidir. Bu nesne yalnızca isErrorPage attributeü true olan JSP sayfalarında bulunur. |
Expression language(EL) in JSP
JSP sayfalarında öntanımlı nesnelere ve sayfaya request üzerinden eklenen bean
lere erişmeyi kolaylaştırmak için kullanılır. Kullanımı şöyledir:
${expression}
Örneğin sırasıyla form.jsp
ve display.jsp
adında iki dosya oluşturup içeriğini aşağıdaki gibi güncelleyelim.
<body>
<form action="display.jsp">
Kullanıcı Adı: <input type="text" name="username" /><br>
Üniversite: <input type="text" name="uni" /><br>
<input type="submit" value="Yolla"/>
</form>
</body>
<body>
Kullanıcı Adı ${ param.username } <br>
Üniversite ${ param.uni }
</body>
Kaynak Kodları İndirin
Yazıdaki tüm örnekleri içeren Eclipse projesini indirin.
veya
git kullanarak clone
la
$ git clone https://github.com/JavaOrnekleri/JSPNedir.git