Java Servlet, Java programlama dilini kullanarak web uygulamaları geliştirmek için kullanılan bir teknolojidir. Bir servlet, bir sunucuda çalışan ve istemci isteklerine yanıt olarak dinamik içerik üreten bir Java programıdır. Genellikle HTTP protokolü üzerinden web isteklerine yanıt vermek için kullanılırlar, ancak diğer protokolleri de destekleyebilirler.
Temel Kavramlar:
Servlet Lifecycle: Servlet'in yaşam döngüsü, genellikle init(), service() ve destroy() metodlarından oluşur. init() metodu, servlet yaratıldığında bir kez çağrılır ve başlangıç konfigürasyonunu yapar. service() metodu, her istek geldiğinde çağrılır ve isteğe bağlı olarak yanıt üretir. destroy() metodu, servlet'in sonlandırılmasından önce çağrılır ve temizleme işlemlerini gerçekleştirir.
Request ve Response: Bir servlet, istemcilerden gelen istekleri HttpServletRequest nesnesi olarak alır ve isteklere HttpServletResponse nesnesi kullanarak yanıt verir. Bu nesneler, HTTP istekleri ve yanıtları ile ilgili tüm bilgileri içerir.
Servlet Container: Servletler, bir servlet container (örneğin Apache Tomcat, Jetty) içinde çalışır. Servlet container, servlet yaşam döngüsünü yönetir, ağ iletişimini sağlar ve servletlere özel bir ortam sunar.
Servlet Geliştirme Adımları:
Servlet Yazma: Bir servlet, javax.servlet.Servlet arayüzünü uygulayarak veya genellikle yapılan gibi javax.servlet.http.HttpServlet sınıfını genişleterek yazılır. İkinci yöntem, HTTP ile ilgili yöntemleri (doGet, doPost vb.) kullanmayı daha kolaylaştırır.
Servlet Konfigürasyonu ve Deployment: Servlet yazıldıktan sonra, bir web uygulamasına yerleştirilir ve web.xml dosyasında veya annotationlar ile yapılandırılır. Bu yapılandırma, servlet'in URL paternleri ile nasıl eşleştirileceğini belirler.
Servlet Çalıştırma: Bir istemci (örneğin bir web tarayıcısı), konfigüre edilmiş URL'ye bir istek gönderdiğinde, servlet container isteği alır ve uygun servlet'i çağırır. Servlet işlemi tamamladıktan sonra, bir yanıt üretir ve bu yanıt istemciye geri gönderilir.
Avantajları ve Kullanım Alanları:
Hız ve Verimlilik: Servletler, istek başına bir süreç veya iş parçacığı oluşturmadan çalıştıkları için CGI (Common Gateway Interface) programlarına göre daha hızlı ve daha verimlidirler.
Platform Bağımsızlık: Java'nın platform bağımsız doğası nedeniyle, servletler çeşitli sunucu ve işletim sistemlerinde çalışabilir.
Güvenlik: Java güvenlik yönetimi, servletlerin güvenli bir şekilde çalışmasını sağlar.
Servletler, dinamik web sayfaları oluşturmak, kullanıcı girişi form verilerini işlemek, veritabanı ile etkileşimde bulunmak ve daha birçok web tabanlı uygulama geliştirme ihtiyacı için kullanılabilir.
Servlet API:
Java Servlet API, servletlerin yazılması ve yönetilmesi için iki ana paket sağlar: javax.servlet ve javax.servlet.http. Bu API, servletlerin istekleri nasıl işleyeceğini, yanıtlar nasıl oluşturulacağını, oturum yönetimini ve diğer birçok işlevi tanımlar.
javax.servlet: Bu paket, tüm servlet türleri için temel sınıflar ve arayüzler içerir. Servlet, ServletRequest, ServletResponse, ServletConfig ve ServletException gibi temel sınıflar bu pakette yer alır.
javax.servlet.http: Bu paket, HTTP ile özel olarak ilgili sınıfları ve arayüzleri içerir. Bu, HTTP protokolünü kullanan servletler için tasarlanmıştır ve HttpServletRequest, HttpServletResponse, HttpSession gibi sınıfları içerir.
Servlet Oturum Yönetimi:
Web uygulamalarında durum yönetimi, çeşitli kullanıcı istekleri arasında bilgi saklamak için önemlidir çünkü HTTP protokolü durumsuzdur. Servlet API, oturum yönetimi için birkaç mekanizma sağlar:
HTTP Cookies: Sunucu tarafından istemciye gönderilen ve istemci tarafından her HTTP isteğiyle birlikte geri gönderilen küçük veri parçaları.
URL Rewriting: Her istekle birlikte kullanıcı oturum ID'sini URL'ye ekleyerek oturum bilgisini takip etme.
Hidden Form Fields: Web formu üzerinde kullanıcıya ait oturum bilgilerini saklayan gizli alanlar.
HttpSession Interface: En popüler yöntemdir. Bir kullanıcıya özgü bir oturum oluşturulur ve kullanıcıyla ilgili veriler bu oturum nesnesinde saklanır.
Servlet Filtreleri:
Servlet filtreleri, isteklerin ve yanıtların servletlere ulaşmadan veya servletlerden çıktıktan sonra işlenmesi için kullanılır. Güvenlik kontrolleri, oturum kontrolü, kayıt (logging), ve içerik manipülasyonu gibi işlevleri gerçekleştirmek için kullanılabilirler. Bir filtre, javax.servlet.Filter arayüzünü uygulayarak oluşturulur ve genellikle web.xml dosyasında veya annotationlar ile yapılandırılır.
Servlet Dinleyicileri (Listeners):
Servlet dinleyicileri, web uygulamasının yaşam döngüsü olaylarına yanıt vermek için kullanılır. Bu, uygulama seviyesinde veri başlatma, oturum oluşturma ve yok etme gibi olaylara müdahale etmek için kullanılabilir. Dinleyiciler, javax.servlet.ServletContextListener, javax.servlet.ServletRequestListener, javax.servlet.HttpSessionListener gibi arayüzleri uygulayarak oluşturulur.
Modern Java Web Geliştirme:
Geleneksel servlet yazımı ve yönetimi zamanla daha yüksek seviyeli çerçevelerle (frameworks) entegre edilmiştir. Spring, JAX-RS gibi çerçeveler, servlet tabanlı uygulamaları daha kolay ve daha yapılandırılabilir hale getirmek için geliştirilmiştir. Ancak, bu çerçevelerin arkasındaki temel teknoloji hala Java Servlet teknolojisidir.
Bu, Java Servlet hakkında genel bir bakış sunar. Daha spesifik konular, örnekler ve en iyi uygulamalar için resmi Java EE Tutorial'ı veya diğer Java kaynaklarını inceleyebilirsiniz.
Java Servlet programlamaya dair bazı temel kod örnekleri aşağıda verilmiştir. Bu örnekler, bir servletin nasıl yazılacağını, basit bir HTTP GET isteğine nasıl yanıt verileceğini ve basit bir HTML formundan gelen verilerin nasıl işleneceğini gösterir.
Basit bir Servlet örneği:
Bu örnek, doGet metodunu kullanarak HTTP GET isteklerine nasıl yanıt verileceğini gösterir. Bu servlet, tarayıcıya basit bir "Hello, World!" mesajı gönderir.
java
Copy code
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class HelloWorldServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Set response content type
response.setContentType("text/html");
// Actual logic goes here.
PrintWriter out = response.getWriter();
out.println("<h1>Hello, World!</h1>");
}
}
HTML Form verilerini işleyen bir Servlet örneği:
Bu örnek, bir HTML formundan gönderilen verileri nasıl alacağınızı ve işleyeceğinizi gösterir. Burada doPost metodu, form verilerini işlemek için kullanılır.
Öncelikle HTML formunu inceleyelim:
html
Copy code
<!-- simpleForm.html -->
<form action="FormHandlerServlet" method="POST">
First Name: <input type="text" name="first_name">
<br>
Last Name: <input type="text" name="last_name">
<input type="submit" value="Submit">
</form>
Şimdi, bu form verilerini işleyecek Servlet:
java
Copy code
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class FormHandlerServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Set response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Get the value of form parameter
String firstName = request.getParameter("first_name");
String lastName = request.getParameter("last_name");
// Logic to use these parameters
out.println("<h1>Received the following details:</h1>");
out.println("<p>First Name: " + firstName + "</p>");
out.println("<p>Last Name: " + lastName + "</p>");
}
}
Servlet konfigürasyonu (web.xml):
Servlet'leri ve URL eşlemelerini tanımlamak için web.xml dosyası kullanılır. Yukarıdaki örnekteki HelloWorldServlet ve FormHandlerServlet servletlerini yapılandırmak için aşağıdaki XML kodunu kullanabilirsiniz:
xml
Copy code
<web-app>
<servlet>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>HelloWorldServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>FormHandlerServlet</servlet-name>
<servlet-class>FormHandlerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FormHandlerServlet</servlet-name>
<url-pattern>/formHandler</url-pattern>
</servlet-mapping>
</web-app>
Bu yapılandırma dosyası, HelloWorldServlet'e /hello yoluyla ve FormHandlerServlet'e /formHandler yoluyla erişilmesini sağlar. Uygulama sunucunuzda bu servletleri ve HTML formunu konuşlandırdıktan sonra, bunları tarayıcınız aracılığıyla test edebilirsiniz.
Servlet Lifecycle Metodları ile İlgili Örnek:
Servlet yaşam döngüsü metodlarını içeren daha detaylı bir servlet örneği verelim. Bu örnekte, init, service ve destroy metodlarının nasıl kullanılacağını görebilirsiniz:
java
Copy code
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class LifecycleDemoServlet extends HttpServlet {
public void init() throws ServletException {
// Initialization code here
System.out.println("Servlet is being initialized");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Respond to GET requests here
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<h2>Servlet Lifecycle Demo</h2>");
out.println("<p>Refresh the page to see the service method in action.</p>");
}
public void destroy() {
// Cleanup code here
System.out.println("Servlet is being destroyed");
}
}
Bu örnekte init() metodu, servlet nesnesi örneği oluşturulduğunda bir kez çalışır. doGet() metodu her GET isteği için çağrılır (HTTP POST istekleri için doPost() metodunu kullanabilirsiniz). destroy() metodu ise servlet'in yaşam döngüsünün sonunda, servlet nesnesi kaldırıldığında bir kez çalışır.
Servlet Filtre Örneği:
Aşağıda, istekleri ve yanıtları işlemek için bir servlet filtresi örneği verilmiştir. Bu filtre, tüm isteklerdeki ve yanıtlardaki geçiş süresini hesaplar ve konsola yazdırır:
java
Copy code
import java.io.*;
import javax.servlet.*;
public class PerformanceFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
// Filter initialization code
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// Get the current time before processing the request
long startTime = System.currentTimeMillis();
// Pass the request and response to the next filter or servlet in the chain
chain.doFilter(request, response);
// Get the current time after processing the request
long endTime = System.currentTimeMillis();
// Calculate and print the time taken to process the request
System.out.println("Time taken: " + (endTime - startTime) + " milliseconds");
}
public void destroy() {
// Filter cleanup code
}
}
Bu filtreyi kullanmak için, web.xml dosyasında filtre ve filtre eşlemesi tanımlamanız gerekir:
xml
Copy code
<filter>
<filter-name>PerformanceFilter</filter-name>
<filter-class>PerformanceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PerformanceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Bu yapılandırma, uygulamadaki tüm sayfalara (/* URL deseni ile) uygulanan filtreleri tanımlar.
Servlet Dinleyici (Listener) Örneği:
Bir uygulama yaşam döngüsü dinleyicisi örneği verelim. Bu dinleyici, uygulama başladığında ve durdurulduğunda mesajlar yazdırır:
java
Copy code
import javax.servlet.*;
public class MyAppListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
System.out.println("Web application is starting");
}
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("Web application is stopping");
}
}
Bu dinleyiciyi kullanmak için, onu web.xml dosyasına eklemeniz gerekiyor:
xml
Copy code
<listener>
<listener-class>MyAppListener</listener-class>
</listener>
Bu örnekler, Java Servlet API'sini kullanarak basit web uygulamaları geliştirmenin temel yönlerini kapsar. Uygulamanızın gereksinimlerine bağlı olarak daha karmaşık işlevsellikler ekleyebilirsiniz.
Servlet Konfigürasyon Parametreleri ile Çalışma:
Servletlerinizi daha esnek hale getirmek için, başlangıç parametreleri kullanarak servlet konfigürasyonunu özelleştirebilirsiniz. Bu parametreler, servlet başlatıldığında yüklenir ve init() metodu içinde kullanılabilir. Aşağıda, bir servletin başlangıç parametrelerini nasıl kullanabileceğine dair bir örnek verilmiştir:
Servlet Kodu:
java
Copy code
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class ConfigDemoServlet extends HttpServlet {
private String myParam = "";
public void init() throws ServletException {
// Servlet initialization code here
myParam = getServletConfig().getInitParameter("exampleParam");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Respond to GET requests here
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<h2>Servlet Configuration Demo</h2>");
out.println("<p>Value of exampleParam: " + myParam + "</p>");
}
}
web.xml Konfigürasyonu:
xml
Copy code
<servlet>
<servlet-name>ConfigDemoServlet</servlet-name>
<servlet-class>ConfigDemoServlet</servlet-class>
<init-param>
<param-name>exampleParam</param-name>
<param-value>Initial Value</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ConfigDemoServlet</servlet-name>
<url-pattern>/configDemo</url-pattern>
</servlet-mapping>
Bu örnekte, ConfigDemoServlet adlı servlet için bir başlangıç parametresi tanımlanmıştır. Servlet başlatıldığında, bu parametrenin değeri init() metodunda alınır ve daha sonra doGet() metodunda kullanılır.
Dosya Yükleme İşlemleri:
Servletler, form üzerinden dosya yükleme işlemlerini de destekler. Dosya yükleme işlemleri için genellikle Apache Commons FileUpload gibi üçüncü parti kütüphaneler kullanılır. Aşağıda basit bir dosya yükleme servleti örneği verilmiştir:
HTML Formu:
html
Copy code
<!DOCTYPE html>
<html>
<body>
<form action="FileUploadServlet" method="post" enctype="multipart/form-data">
Select a file to upload: <input type="file" name="file">
<input type="submit" value="Upload File">
</form>
</body>
</html>
Servlet Kodu:
Bu örnek, Apache Commons FileUpload kütüphanesini kullanır. Bu kütüphaneyi kullanmadan önce, proje bağımlılıklarınıza eklemeniz gerekebilir.
java
Copy code
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class FileUploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart) {
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
try {
// Parse the request to get file items.
List<FileItem> items = upload.parseRequest(request);
// Process the uploaded items
for (FileItem item : items) {
if (!item.isFormField()) {
// Process form file field (input type="file").
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
boolean isInMemory = item.isInMemory();
long sizeInBytes = item.getSize();
// Write the file
if (fileName.lastIndexOf("\\") >= 0) {
File uploadedFile = new File(getServletContext().getRealPath("/")
+ fileName.substring(fileName.lastIndexOf("\\")));
item.write(uploadedFile);
} else {
File uploadedFile = new File(getServletContext().getRealPath("/")
+ fileName.substring(fileName.lastIndexOf("\\")+1));
item.write(uploadedFile);
}
} else {
// Process regular form field (input type="text|radio|checkbox|etc", select, etc).
String name = item.getFieldName();
String value = item.getString();
// You can process the values here; for example, store them in a database
}
}
} catch (Exception ex) {
throw new ServletException(ex);
}
}
// Redirect or forward to a completion page, or write out confirmation to the response.
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><head><title>Upload Result</title></head><body>");
out.println("<p>File uploaded successfully!</p>");
out.println("</body></html>");
}
}
Bu örnekte, FileUploadServlet sınıfı, multipart/form-data türünden gelen istekleri işler, yani dosya yükleme işlemleri için kullanılır. Servlet, yüklenen dosyayı sunucuda belirli bir konuma kaydeder. DiskFileItemFactory ve ServletFileUpload sınıfları, Apache Commons FileUpload kütüphanesinin bir parçasıdır ve yükleme işlemi için gerekli işlevselliği sağlar.
Dosya yükleme işlemi sırasında, parseRequest(request) metodu isteği analiz eder ve form alanları ile yüklenen dosyaları içeren bir FileItem listesi döndürür. Dosyalar ve form alanları bu listeden çıkarılır ve işlenir. Örneğin, bir dosya alandıysa, isFormField() metodu false değerini döndürür ve dosyanın işlenmesi gerekir.
Yüklenen dosyalar sunucunun dosya sistemine kaydedilir. Burada, yüklenen dosyanın adını ve yolu getServletContext().getRealPath("/") kullanarak belirliyoruz, bu da uygulamanın kök dizinini döndürür. Bu şekilde, yüklenen dosyalar sunucunun belirli bir klasörüne kaydedilir.
Dosya yükleme işlemi tamamlandıktan sonra, kullanıcıya bir onay mesajı gösterilir. Bu, işlemin başarılı olduğunu teyit eder ve kullanıcıya geri bildirim sağlar.
Bu örnek, Java Servlets kullanılarak web tabanlı bir dosya yükleme işlevinin nasıl gerçekleştirileceğinin temel bir örneğidir. Gerçek dünya uygulamalarında, dosya yükleme işlemleri daha karmaşık güvenlik kontrolleri, dosya boyutu ve tipi kısıtlamaları, hata yönetimi ve kullanıcı geri bildirim mekanizmaları içerebilir.
Servlet Session Örneği:
Bu örnekte, bir HTTP oturumunda bir kullanıcının ziyaret sayısını takip eden bir servlet gösterilmektedir.
java
Copy code
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class SessionTrackServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Set response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Create or retrieve current session
HttpSession session = request.getSession(true);
// Retrieve the current count from the session, if any
Integer count = (Integer)session.getAttribute("count");
if (count == null) {
count = 1; // Initialize counter if not already initialized
} else {
count = count + 1; // Increment the count
}
// Store the updated count in the session
session.setAttribute("count", count);
// Display the count to the user
out.println("<html><head><title>Session Tracking Demo</title></head>");
out.println("<body><h2>You have visited this page " + count + " times.</h2></body></html>");
}
}
Bu örnekte, getSession(true) metodu kullanılarak bir oturum oluşturulur veya mevcut oturum alınır. getAttribute ve setAttribute metodları kullanılarak oturum verisi alınır ve güncellenir. Kullanıcı her ziyaretinde, sayı bir artırılır ve kullanıcıya kaç kez ziyaret ettiği bildirilir.
Servlet Cookie Örneği:
Bu örnekte, bir kullanıcı adının çerezler kullanılarak nasıl saklanacağı ve geri alınacağı gösterilmektedir.
java
Copy code
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class CookieExampleServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Set response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// Attempt to retrieve existing cookies
Cookie[] cookies = request.getCookies();
String username = null;
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("username")) {
username = cookie.getValue();
}
}
}
// Check if the user name is not found in cookies
if (username == null) {
username = "Guest";
// Create a new cookie
Cookie newUserCookie = new Cookie("username", "Tom");
newUserCookie.setMaxAge(60*60*24); // Store cookie for 1 day
response.addCookie(newUserCookie);
}
// Display the user name
out.println("<html><head><title>Cookie Example</title></head>");
out.println("<body><h2>Hello, " + username + "!</h2></body></html>");
}
}
Bu örnekte, getCookies() metodu kullanılarak istemciden gönderilen çerezler alınır. Eğer belirli bir isimde (bu örnekte "username") bir çerez mevcutsa, bu çerezin değeri alınır. Eğer çerez mevcut değilse, yeni bir çerez oluşturulur ve istemciye gönderilir (addCookie metodu ile). Bu yeni çerez, sonraki isteklerde sunucuya gönderilir ve kullanıcı adı gibi bilgiler saklanabilir.
Bu basit örnekler, Java Servletlerde oturum ve çerez yönetiminin nasıl kullanılacağını göstermektedir. Gerçek dünya uygulamalarında, güvenlik önlemleri, oturum süresi yönetimi ve çerezlerin güvenli şekilde saklanması gibi konular da dikkate alınmalıdır.