← Back to list

Tomcat ve Servlet Nedir?

Başlamadan belirtmekte fayda var, burada derinlemesine bakmayacağım,

Furkan Tatar · 2026-05-08 22:51 · 0 claps · 5.4 min read
#java #spring-boot #tomcat #servlet #software-architecture
Open on Medium ↗
Wiki topics: 🏛️ · Architecture

Tomcat ve Servlet Nedir?

Başlamadan belirtmekte fayda var, burada derinlemesine bakmayacağım,

zaten bunu yazdığım tarih için derinleme bir bilgim olduğunu düşünmüyorum bu konu hakkında ancak aklımda boşluk olmasındansa kendimce soruya verdiğim bir cevap bu.

Öncelikle belirtelim Tomcat ve Servlet yapıları Java’ya ait yapılardır,

Bu yapıları şu şekil kabaca tanımlayalım:

TOMCAT: Dışarı ile ilgilenen kısmımızdır. Sunucumuzu ayağa kaldıran (8080 portunu tutan) ayrıca buraya gelen çirkin HTTP isteklerini parçalayıp uygun hale getirerek, ilgili servlet metoduna yönlendiren kişidir.

SERVLET: İç işleyişle ilgilidir, kendisine gelen request nesnelerini Business Logic ile işleyip geriye bir response nesnesi döner.

Bu ikisini verdikten sonra şu cümleyi kurmak da doğru olacaktır, Tomcat bir Servlet Container’ıdır.

Şimdi ilkel bir sunucu ayağa kaldırıp bu işlemi temel seviyede de olsa gözümüzle görelim.

  1. Tomcat için ilk işlemimiz bir port tutmak; ServerSocket server = new ServerSocket(8080);

Bu noktada artık cihazımız bir sunucudur, yani bizim bu kodu çalıştırdığımız cihazdaki bu porta gelen her istek artık bilgisayarımız tarafından karşılanır.

yine cihazımızda http://localhost:8080 yazarsak istek bu socket’e gider (zaten bu noktada hâlâ kendi cihazımızın içindeyiz)

Çirkin Http isteklerini parçalayıp uygun hale getirir demiştik, ne o http istekleri ki nasıl parçalayalım?

GET / HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Content-Type: application/json
Content-Length: 45
Accept: */*
Cookie: sessionId=abc123xyz; userToken=f4782
Connection: keep-alive
...

Kabaca yukarıdaki gibi bi istek gelicektir bize, biz ilkel Tomcat kodumuzda detaylarla ilgilenmeyeceğiz (çünkü o kadar yetkinliğim yok şu anda :D) bizim işimiz ilk satırla;

“GET / HTTP/1.1”

Yani atılan istek ‘GET’ ve yolu ‘/’, biz bu bilgiyi string manipülasyonla parçalarsak artık hangi endpoint’e istek atmış bulabiliriz.

// 1. ADIM: Gelen satırı parçala (Örn: "GET /haberler HTTP/1.1")
String[] parts = line.split(" ");
String method = parts[0]; // GET
String path = parts[1];   // İstenen yol (/) veya (/yazilar)
  1. Artık endpoint yolunu biliyorsak parçalama ile bundan sonra ilgili servlet’e yönlendirebiliriz ki bu işlem if-else işlemlerinden ibaret.

Bundan sonra yönlendirdiğimiz servlet işini yapar ve bize cevabı döner, Servlet’i netleştirmeden örnek bir server kaldıralım.

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class PrimitiveServer {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(8080);
        System.out.println("Server 8080 portunda hazır...");

        while (true) {
            try (Socket client = server.accept()) {
                BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                String line = in.readLine();
                if (line == null) continue;

                // 1. ADIM: Gelen satırı parçala (Örn: "GET /haberler HTTP/1.1")
                String[] parts = line.split(" ");
                String method = parts[0]; // GET
                String path = parts[1];   // İstenen yol

                System.out.println(method + " isteği geldi: " + path);

                // 2. ADIM: Basit bir If-Else ile Yönlendirme (Primitive Router)
                String responseBody;
                String status = "200 OK";

                if (path.equals("/")) {
                    responseBody = "<html><body><h1>Ana Sayfaya Hos Geldin!</h1></body></html>";
                } else if (path.equals("/yazilar")) {
                    responseBody = "<html><body><h1>Ders Listesi: Java, OS, Network</h1></body></html>";
                } else {
                    // Tanımlı olmayan her şey için 404 dönüyoruz
                    status = "404 Not Found";
                    responseBody = "<html><body><h1>404 - Boyle Bir Sayfa Yok Kanka</h1></body></html>";
                }

                // 3. ADIM: Yanıtı HTTP formatında paketle
                String httpResponse = "HTTP/1.1 " + status + "\r\n" +
                        "Content-Type: text/html; charset=UTF-8\r\n" +
                        "Content-Length: " + responseBody.getBytes("UTF-8").length + "\r\n" +
                        "Connection: close\r\n" +
                        "\r\n" +
                        responseBody;

                OutputStream out = client.getOutputStream();
                out.write(httpResponse.getBytes("UTF-8"));
                out.flush();
            }
        }
    }
}

Koda bakarsak tomcat kaldırılmış, yönlendirme yapılmış ve ilgili servlet’e (burada olmasa da) yönlendirilmiş, en son ise tabii ki cevabımızı da tekrar http nesnesine çevirip yollamışız.

Bu kodu Java’da yazıp çalıştırdığınızda artık bilgisayarınızda http://localhost:8080 ile erişebilirsiniz veya http://localhost:8080/dersler ile erişebilirsiniz.

EGLENMEK İSTEYENLER İÇİN AŞAĞISI

Dahası şu anda cihazınızın ip:port şeklinde açıkta bir sunucu halinde yani siz AYNI AĞDA olduğunuz bir telefonda bu kodu kaldırdığınız cihazın ip adresi ile erişebilirsiniz.

Mesela 176.16.0.0 agında hem bilgisayarınız hem telefonunuz var. Bilgisayarınızın (sunucunuz) ip’si 176.16.0.5 diyelim, telefonunuz da 176.16.0.x ip’sinde,

Telefonunuzdan http://176.16.0.5:8080 veya http://176.16.0.5:8080/dersler isteği attığınızda sizin bilgisayarınız (sunucu) isteği karşılayacaktır.

EĞER BURADAN SONRASINI OKUMAK İSTEMEZSENİZ “GÜNÜMÜZ” KISMINA ATLAYIN.

Peki şimdi bunu biraz daha modernleştirsek? Hem görevleri iyice ayrıştırırız hem de bir servlet tasarımını görmüş oluruz. sistemimiz “Primitive+” olsun :p

Öncelikli işimiz bu gelen response ve request için veri aktarım objeleri(dto) tasarlamak ki sistemimiz olsun, ayrıca ana kodun içinden ayrılsın.

// Sadece gelen path'i tutan basit bir sınıf
class MyRequest {
    public String path;
    public MyRequest(String path) { this.path = path; }
}

// Yanıtı biriktirdiğimiz sınıf
class MyResponse {
    private StringBuilder body = new StringBuilder();
    public void write(String content) { body.append(content); }
    public String getBody() { return body.toString(); }
}

MyRequest isteği constructor’ında bize parçalanıp gelen endpoint yolunu alıyor ve direkt olarak isteğe basıyor.

MyResponse ise şöyle kurgulayalım; bu bize boş tepsi verir, kodun yol üstünde biz bulduğumuz/lazım olanları buna veririz ve uç uca biriktirerek ilerletir. write fonksiyonu istenileni alıp içerdeki “body” degişkeninin ucuna ekleyerek gider; getBody fonksiyonu ise tepsi hazır demektir, tepsinin bütününü String olarak geriye döner (Detaylı öğrenmek isterseniz bu bir builder tipi sınıftır)

Diğer Servlet’lerimizin kullanacağı ve onu implement edenlerin, bahsedilenleri kullanmakta sözleştiği interface sınıfını yazalım:

interface MyServlet {
    void service(MyRequest req, MyResponse res);
}

(böylece demin yazdığımız dto’larımızla işlem yapılacağını ayrıca service metodunun herkeste varolacağını garantiliyoruz)

Daha sonra bunu implement eden ve asıl işi yapıp cevabı dönecek olan servletlerimizi yazalım:

class HomeServlet implements MyServlet {
    public void service(MyRequest req, MyResponse res) {
        res.write("<h1>Ana Sayfadasın</h1><p>Tomcat ilkel router calisiyor.</p>");
    }
}

class AboutServlet implements MyServlet {
    public void service(MyRequest req, MyResponse res) {
        res.write("<h1>Hakkımızda</h1><p>Ben bir baska servletim!</p>");
    }
}

Tamamdır artık servletlerimiz hazır ve içlerindekileri write yapıyor, en son cevabımız ise zaten o yazılanı dönüyor response olarak. artık MyServlet interface’i ile diğer servletlerden hizmet alabiliriz ancak son olarak bir router sistemi kuralım.

class MyRouter {
    private Map<String, MyServlet> routes = new HashMap<>();

    // Yeni rotalar eklemek için
    public void addRoute(String path, MyServlet servlet) {
        routes.put(path, servlet);
    }

    // Gelen isteği ilgili Servlet'e paslamak için (Dispatch işlemi)
    public void dispatch(MyRequest req, MyResponse res) {
        MyServlet servlet = routes.get(req.path);

        if (servlet != null) {
            servlet.service(req, res);
        } else {
            res.write("<h1>404</h1><p>Router bu yolu bulamadi. </p>");
        }
    }
}

Burası içeriğinde String Key alıp, MyServlet tipinde Value veren bir hashmap tutuyor,

addRoute metodu parametresine key ve value değerini alıp hashmap’e ekliyor,

dispatch metodu ise req’den (içinde endpoint var sadece dedik) path’i alıyor ve bunu hashmap’e key olarak verip servlet degişkenine ilgili servleti alıyor;

servlet null degilse ilgili servlet’in service metodunu çalıştırıyor, servlet null ise bu yol yok bilgisini cevabı oluşturacak tepsiye yazıyor.

Artık her şey tamam olduğuna göre şimdi sunucumuzu ayağa kaldırabiliriz:

public class PrimitiveServerPlus {

    public static void main(String[] args) throws IOException {
        // Rotaları Kaydet
        MyRouter router = new MyRouter();
        router.addRoute("/", new HomeServlet());
        router.addRoute("/about", new AboutServlet());

        //8080 portunu al
        ServerSocket server = new ServerSocket(8080);
        System.out.println("Sistem Hazir! Tarayicidan http://localhost:8080/ veya /about yaz...");

        while (true) {
            try (Socket client = server.accept()) {
                // ISTEGI OKUMA (Parsing)
                BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                String firstLine = in.readLine(); // "GET /about HTTP/1.1"

                if (firstLine == null || firstLine.isEmpty()) continue;

                // Path'i ayıkla
                String path = firstLine.split(" ")[1];
                System.out.println("Gelen İstek Yolu: " + path);

                // NESNELERI OLUSTUR (Request & Response)
                MyRequest req = new MyRequest(path);
                MyResponse res = new MyResponse();

                // YONLENDIRME (Routing)
                router.dispatch(req, res);

                // YANITI PAKETLE VE GONDER (The Final Response)
                String responseBody = res.getBody();
                String fullResponse = "HTTP/1.1 200 OK\r\n" +
                        "Content-Type: text/html; charset=UTF-8\r\n" +
                        "Content-Length: " + responseBody.getBytes().length + "\r\n" +
                        "\r\n" +
                        responseBody;

                OutputStream out = client.getOutputStream();
                out.write(fullResponse.getBytes("UTF-8"));
                out.flush();

            } catch (Exception e) {
                System.err.println("Bir hata olustu: " + e.getMessage());
            }
        }
    }
}

Sunucu 8080 portunu aldı ve işleri yapması için kişileri organize etti, en sonunda ise response’u http formatına çevirip yolladı.

Servlet’lerin amacı ise kendilerine yönlendirilmiş olan bu istekleri alıp kendi içlerinde Business Sınıfının işini yapar gibi işleyip veriyi, yollamak oldu; her ne kadar bu kodda doğrudan düz cevap döndürsek de.

GÜNÜMÜZ

  1. Günümüzde Tomcat hiçbir rota vs bilmez, çünkü artık tek bir servlet vardır. Tomcat artık sunucuyu (8080) kaldırır ve dinler, gelen request’i alıp paketleyip direkt o tek servlet’e verir.
  2. Günümüzde Servlet olarak sadece DispatcherServlet isimli servlet vardır, gelen her istek buraya gelir ve DispatcherServlet elindeki HandlerMapping bakar ve “Bu isteği hangi Controller’ın hangi metodu çözebilir?” diyerek bulur.
  3. Günümüzde artık bu HomeServlet, AboutServlet sınıfları aslında birer Controller oldu, @RestController yazarız ve o halleder. Aynı şekilde içeriğindeki ağır business logic’ler ise Business package’ına devredilmiş oldu.

Günümüzdeki Akışın Özeti

  1. İstek Gelir: Tomcat isteği karşılar.
  2. Kime Gidecek? -> Tomcat doğrudan DispatcherServlet'e paslar.
  3. Yönlendirme (Routing): DispatcherServlet @GetMapping etiketlerine bakarak ilgili Controller metodunu bulur.
  4. İş Mantığı (Business): O metot çalışır, veriyi hazırlar.
  5. Yanıt: Spring, senin döndüğün objeyi (veya String’i) otomatik olarak HTTP Response formatına sokar ve Tomcat üzerinden kullanıcıya gönderir.

메타데이터
post_id
7f9e7edfe8ed
slug
tomcat-ve-servlet-nedir-7f9e7edfe8ed
url
https://medium.com/@furkn.ttr/tomcat-ve-servlet-nedir-7f9e7edfe8ed
canonical_url
https://medium.com/@furkn.ttr/tomcat-ve-servlet-nedir-7f9e7edfe8ed
author_url
https://medium.com/@furkn.ttr
status
ok
fetched_at
2026-07-14 23:28:58