Bir servletten başka yere köprü kurarak, içinde obje de taşımak mümkün olan bir transfer çeşididir.
req.getRequestDispatcher(path) ;
req.setAttribute("...",entity);
dispatcher.forward(req,resp);
//entity buradaki req. parametresine yani requeste eklendi
//forward ile gönderildi.
şeklinde path adresine bir entity (yani nesne) transfer etmek mümkündür.
Bunun sebebi GET ya da POST kullanmadan yazmak istediğimiz içindir.
GET ile gönderilseydi GET abc?username=user&password=pass şeklinde de gönderilebilirdi.
Servlet tasarımı kötü olduğundan ve basit bir işlem için çok fazla kod yazmak gerektiğinden kullanışlı değildir.
Servleti view olarak kullanmayız. Yani karmaşık olduğundan kullanıcıyla iletişime girmiyor.
Servlet ile JSP birbirine alternatif gibi görünse de aslında beraber çalışan teknolojilerdir.
MVC yani Model-View-Controller patternindeki view olarak JSP sayfaları, controller olarak da Servlet sınıfları kullanılıyor.
- name : formun adı.
- method: form verisi gönderilirken kullanılacak olan HTTP metodu (GET ya da POST)
- action: servlet'in URL'si (başına '/' karakteri koymamaya dikkat etmek gerekiyor)
Yani servletin map'lendiği URL.
Örneğin web.xml'deki servlet mapping alanında şunlar belirtilmişse:
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.example.servlets.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/loginServlet</url-pattern>
</servlet-mapping>
Bu servleti formda action kısmında action="loginServlet" olarak belirtmek gerekir.
Burada olan şey, login butonuna tıklandığı anda formun verilerini bir mesaja yükleyerek servletin url'sini çağırmaktır. Servlet gereken cevabı /loginServlet URL adresinde bir html sayfası şeklinde gösterir.
Yani client /loginServlet adlı URL'yi istediğinde, servera önceden hazırlanıp konmuş olan sabit bir loginServlet.html sayfası döndürülmüyor.
Aksine, /loginServlet URL adresine maplenmiş olan, yani o adresin çağrılmasından sorumlu olan servlet dinamik olarak bir html sayfası yaratarak, belirtilen URL adresinde bu sayfayı browsera yazıyor.
İşte servletin dinamik olması buradan geliyor.
Login'e tıklandığında neler oluyor?
Form doldurulup "Login" butonuna tıklandığı anda browser servlet containera (Örneğin Tomcat server) bir HTTP POST isteği gönderir:
POST .../loginServlet HTTP/1.1
Host: xxx
Bu istek mesajının body kısmında da
username=asd&password=asd
yazacaktır.
Servlet container (yani sunucu) bu mesajı alır. Aldığı anda service() metodu aracılığıyla gelen HTTP POST mesajını delege ederek LoginServlet instance yaratıp initialize eder(eğer henüz yaratılmamışsa). Ve bu instance'ın doPost() metodunu çalıştırır.
Servletin doPost() metodunda gelen istek bilgileri okunup cevaplanır.
<input>
Formun içinde input elemanları mevcut.
input tagı kullanıcının veri girişi yapabileceği alanları belirtir.
input tagının attribute'leri:
-name: input alanının adı.
Servlet içerisinde istek parametrelerini almak için kullanılan HttpServletRequest nesnesinin getParameter(name) metodundaki name budur.
Input alanına sayı girilmesi gerekiyorsa, servlet içerisinde bunu int yada double olarak parse ederek kullanabiliriz.
- type: girilecek veri tipi.
"text" : yazı açık şekilde görülür.
"password" olursa yıldızlanarak gizlenir, ekranda şifrenin gizlenmesi sağlanır.
"checkbox" : tıklama kutusu.
"radio" : radyo butonu
"submit" olursa bir submit butonu oluşturulur. value ile verilen değer butonun üzerine yazılır.
1. Öncelikle environment'ta path değişkeninde JDK_HOME\bin bulunduğunu kontrol etmek gerekiyor. Bunu tanımlamadıkça komut satırından javac ve jar toollarına erişemiyoruz.
Servlet, client'tan gelen istekleri işleyip cevap gönderen bir server-side component'tir.
Tipik bir Java EE application'daki temel birimlerden biridir.
Diğerleri JSP, EJB, XML, vb'dir.
Servlet genelde JSP ile beraber client'tan gelen isteklere göre dinamik içerik yaratmakta kullanılır.
Servletler HttpServlet sınıfının doGet() ve doPost() metodlarını override ederek GET ve POST isteklerini yönetirler.
Örnek bir senaryoda:
1. JSP ile kullanıcının dolduracağı bir form gösterilir.
2. Form doldurulup gönder butonuna tıklandığında servlet çağırılır.
3. Servlet kullanıcının yazdığı veriyi işleyerek ona göre bir cevap gönderir.
Örneğin formun başında kullanıcının girdiği e-posta adresinin hatalı olduğunu belirten kırmızı bir uyarı yazısı belirebilir.
Ya da bazı alanların boş bırakılmaması gerektiği belirtilebilir.
Servlet container nedir?
Servlet container, java servletleri çalıştırabilen bir web server'dır.
Container sayesinde threadler, güvenlik, JSP processing, networking gibi konularla uğraşmamıza gerek kalmaz.
Container bizim için bunları kendisi hallettiğinden, biz sadece business logic üzerinde çalışabiliriz.
Not:Her web server, servlet container olamaz.
Örneğin Apache HTTP Server, sadece statik HTML sayfalarını sunabilir.
Fakat java servletleri çalıştıramaz. Bu yüzden de servlet container olamaz.
Tomcat ise hem HTTP listener, hem de JSP/servlet engine içerdiğinden hem statik, hem de dinamik HTML sayfalarını sunabilir. Bu yüzden servlet container olabilir.
En çok kullanılan servlet containerlar:
- Apache Tomcat
- Glassfish
- JBoss
- WebLogic
Servlet container istek ve cevapların kullanılabilmesi için servlete HttpServletRequest ve HttpServletResponse nesneleri verir.
Servlet bu nesneler aracılığıyla istekleri inceler ve cevapları hazırlar.
Servlet life cycle / yaşam döngüsü
Servlet container, yaşam döngüsü boyunca servletin şu metodlarını tetikler (invoke):
1. init()
Servletin yaşam döngüsünde (life cycle) bir kere çağırılır.
Client ilk kez servleti çağırdığında, servlet container bu metodu tetikler.
Burada genelde initialization kodları konulur.
2. doGet()
Client servlete HTTP GET isteğinde bulunduğu her seferde, bu metod tetiklenir.
Bu metoda servlet container iki nesne enjekte eder:
a. HttpServletRequest
Bu nesne istek parametreleri ve headerlarını wrap'ler.
Böylece servlet, getParameter() ve getHeader() metodlarını kullanarak client'ın yolladığı mesajın parametre ve headerlarına erişebilir.
b. HttpServletResponse
HTTP response headerlarını set etmek için ya da client'a HTML içeriği göndermek için kullanılır.
3. doPost()
Client servlete HTTP POST isteğinde bulunduğu her seferde bu metod tetiklenir.
Bu metodun aldığı iki parametre doGet() ile aynıdır.
Servlet, HttpServletRequest nesnesi ile client'tan gelen parametreleri alarak, işledikten sonra oluşan cevabı HttpServletResponse nesnesi ile client'a gönderir.
4. destroy()
Servlet container, web application durdurulacağı zaman ya da server kapanacağı zaman bu metodu tetikler.
Java ile dinamik web sayfası yapmanın bir çok yolu vardır. Bunlardan birisi servlet'tir. Servlet, clientten gelen isteğe göre cevap döndüren bir java classıdır.
Bu cevabı client'a önceden belirlenmiş formatta bir web sayfası olarak döndürür.
Javadoc'taki bilgilere göre, javax.servlet interface'i bütün servletlerin implement etmesi gereken metodları içeriyor.
public interface Servlet
Defines methods that all servlets must implement.
A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol.
To implement this interface, you can write a generic servlet that extends javax.servlet.GenericServlet or an HTTP servlet that extendsjavax.servlet.http.HttpServlet.
This interface defines methods to initialize a servlet, to service requests, and to remove a servlet from the server. These are known as life-cycle methods and are called in the following sequence:
The servlet is constructed, then initialized with the init method.
Any calls from clients to the service method are handled.
The servlet is taken out of service, then destroyed with the destroy method, then garbage collected and finalized.
In addition to the life-cycle methods, this interface provides the getServletConfig method, which the servlet can use to get any startup information, and the getServletInfo method, which allows the servlet to return basic information about itself, such as author, version, and copyright.
Bu interface'i implement eden GenericServlet sınıfı ( javax.servlet.GenericServlet ) genel amaçlı servlet sınıfıdır. Bu sınıftan kalıtım alarak örneğin bir ftp servlet de yazabiliriz.
HttpServlet sınıfı işte bu GenericServlet'in alt sınıfıdır. HttpServlet ten kalıtım alındığında en azından bir metodu override etmek gerekir: genellikle doGet ya da doPost override edilir.
(Not: genellikle google seo konusundaki avantajı yüzünden doGet tercih ediliyor.)
Provides an abstract class to be subclassed to create an HTTP servlet suitable for a Web site. A subclass of HttpServlet must override at least one method, usually one of these:
doGet, if the servlet supports HTTP GET requests
doPost, for HTTP POST requests
doPut, for HTTP PUT requests
doDelete, for HTTP DELETE requests
init and destroy, to manage resources that are held for the life of the servlet
getServletInfo, which the servlet uses to provide information about itself
There's almost no reason to override the service method. service handles standard HTTP requests by dispatching them to the handler methods for each HTTP request type (the doXXX methods listed above).
Likewise, there's almost no reason to override the doOptions and doTrace methods.
Servlets typically run on multithreaded servers, so be aware that a servlet must handle concurrent requests and be careful to synchronize access to shared resources. Shared resources include in-memory data such as instance or class variables and external objects such as files, database connections, and network connections. See the Java Tutorial on Multithreaded Programming for more information on handling multiple threads in a Java program.
HTTP servlet nasıl çalışır?
1. Client servera request gönderir.
2. Server'da bu isteğe ait servlet belirlenir. Request bu servlete gönderilir.
3. Servlet bu gelen bilgileri alır ve oluşturulması gereken sonuçları üretir. Genellikle bu sonuçlar HTML sayfası şeklindedir.
4. Servlet oluşturduğu sonucu web servera gönderir.
5. Web server servletten aldığı sonucu requestin sahibi olan client'a gönderir.
HttpServlet class'ı
HTML isteklerini anlayarak, HTML response üretir.
HttpServlet classını extend ederek kendi servlet'lerimizi yazabiliriz.
Bunun için önce Source Packages altına yeni bir package yaratarak içerisine servlet classlarını atarız.
Daha sonra JNDI için servletleri tanımlamamız gerekir.
Bunu yapmanın 2 yolu var:
1- web.xml ile, (Servlet 3.0 dan itibaren opsiyoneldir)
2-Annotation ile. (JSR-315 (Servlet 3.0) specification ile getirildi)
İki yöntemin de artıları ve eksileri var.
Not: Hem annotation, hem de web.xml de tanımlama yapılırsa annotation xml'i ezer.
Bu yöntemin avantajı tek bir dosyada ekleme-çıkarma, değiştirme yapmanın kolay olmasıdır.
Ayrıca değişiklik yapıldığında serveri yeniden başlattığımız anda web.xml'in yeniden okunmasıyla değişiklikler geçerli olur.
Yapılacak işlemler:
WEB-INF klasörü içerisine yeni bir web.xml dosyası yaratırız.
Buraya servletleri tanımlarız.
Örneğin: IndexServlet.java adlı servlet'i tanımlarken, Servlets tabından add servlet element seçeneğini seçeriz.
Açılan add servlet penceresinde servlet adı, sınıfı, ve URL pattern belirtiriz (posts/* gibi).
Servlet 3.0dan itibaren gelen bir yenilikle, servlet classının başına @WebServlet annotationı koyarak kolay bir şekilde tanımlama yapabiliriz.
web.xml dosyasına gitmeye gerek kalmadan, hızlı bir şekilde tanımlama işi halledilmiş olur.
Fakat burada yapılan bir değşikliğin etkisini göstermesi için bütün projenin yeniden compile edilmesi gerekir. Çünkü burada değişiklik class bazında olmaktadır.
Bu yüzden ufak bir değişiklikte bile bütün projeyi tekrardan compile etmek pek akıl karı değildir.
Gelen isteğin tipine bakarak, kendi içeriğinde bulunan bu isteğe uygun metotları çalıştırır. Bu metodların adları “do” ile başlar: doGet ( ) , doDelete ( ) , vb.
Override edilmesi mümkündür fakat gereği yoktur.
init() metodu
Servlet ilk çalıştığında yapılacak genel işlemler için kullanılır.
Örneğin; veri tabanına bağlantı kurulması gerekiyorsa, bu işlemi bir kere init ( ) metodunda oluşturup gelen bütün isteklerde o bağlantıyı kullanabiliriz.
Yazdığımız servletin yaratılırken haber vermesini istiyorsak init() metodunu override ederiz.
Örnek bir Http Servlet
Projeye sağ tıklayıp Create new -> servlet diyerek yeni servlet yaratabiliriz.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorld extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World!</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello World!</h1>");
out.println("</body>");
out.println("</html>");
}
}
web.xml dosyası
Bir java servletin browserdan erişilebilmesi için önce servlet containera bunu bildirmek gerekiyor.
Servlet containera şunların bildirilmesi gerek:
1-hangi servletleri deploy edeceği
2-bu servletlerin hangi URLlere map edileceği
Web applicationın web.xml dosyasına bunları ilave ederek servlet containerı bilgilendirmiş oluyoruz.
Yani web.xml'deki servlet tanımının ilk bölümünde servlete bir isim verip class adını belirtiyoruz.
Buradan IndexServ adlı servletin aslında com.example.servlets paketinde bulunan IndexServlet sınıfında bulunduğunu anlıyoruz.
İkinci bölümde de servlete verilen isim bir URLe map ediliyor.
IndexServ adlı servletin sadece root'ta bulunan administrator sayfasında çalıştığını anlıyoruz.
HTTP servlet ile gelen requestin parametrelerini kontrol edebiliyoruz. Şöyle ki:
String username = req.getParameter("username");
yazdığımızda örneğin bir formdan gelen kullanıcı adı parametresini alıp username adlı local değişkene vermiş oluruz. Daha sonra parametrelerin doğruluğunu kontrol edip ona göre bir request hazırlayabiliriz.
Bunun dışında request mesajının headerlarını da inceleyebiliriz.
//bütün headerları alır
Enumeration<String> headers = req.getHeaders();
//host headerının değerini alır
String host = req.getHeader("host");
Servlet requestte gelen parametre vb bilgileri alıp gerekli işlemleri yaptıktan sonra duruma göre bir cevap yani response hazırlar. İşte bunu doGet metodundaki HttpServletResponse parametresini kullanarak yapıyoruz.
//response parametresi bize bir PrintWriter sağlıyor
PrintWrite pw = resp.getWriter();
//bununla yazdığımız her şey browser ekranına sanki konsola yazarmışçasına basılıyor.
pw.println("<html><body><p>Hello</p></body></html>");
...
Servlet attribute'leri
value
or
urlPatterns
String[]
Required
Specify one or more URL patterns of the servlet. Either of attribute can be used, but not both.
name
String
Optional
Name of the servlet
displayName
String
Optional
Display name of the servlet
description
String
Optional
Description of the servlet
asyncSupported
boolean
Optional
Specify whether the servlet supports asynchronous operation mode. Default is false.
initParams
WebInitParam[]
Optional
Specify one or more initialization parameters of the servlet. Each parameter is specified by@WebInitParam annotation type.