Java Web Basic – Tag 1 von 10
Von Elyndra Valen, Senior Developer bei Java Fleet Systems Consulting


🗺️ Deine Position im Kurs

TagThemaStatus
→ 1Java EE Überblick & HTTP 👉 DU BIST HIER!
2HTTP-Protokoll Vertiefung & Zustandslosigkeit🔒 Noch nicht freigeschaltet
3Servlets & Servlet API🔒 Noch nicht freigeschaltet
4Deployment Descriptor & MVC vs Model 2🔒 Noch nicht freigeschaltet
5JSP & Expression Languages (Teil 1)🔒 Noch nicht freigeschaltet
6Java Beans, Actions, Scopes & Direktiven🔒 Noch nicht freigeschaltet
7Include-Action vs Include-Direktive🔒 Noch nicht freigeschaltet
8JSTL – Java Standard Tag Libraries🔒 Noch nicht freigeschaltet
9Java Web und Datenbanken – Datasource🔒 Noch nicht freigeschaltet
10Connection Pools & JDBC in Web-Umgebungen🔒 Noch nicht freigeschaltet

Modul: Java Web Basic
Gesamt-Dauer: 10 Arbeitstage (je 8 Stunden)
Dauer heute: 8 Stunden
Dein Ziel: Verstehe die Architektur von Java EE und die Rolle des Application Servers


📋 Voraussetzungen für diesen Tag

Du brauchst:

  • ✅ JDK 21 LTS installiert (OpenJDK oder Amazon Corretto)
  • ✅ Apache NetBeans 22 (oder neuer)
  • ✅ Payara Server 6.x (Application Server – wir installieren ihn heute zusammen)
  • ✅ XAMPP mit MariaDB ab Version 11.6.2 (oder Standalone MariaDB)
  • ✅ Solide Java SE Kenntnisse (Klassen, Objekte, Collections, Vererbung)
  • ✅ HTML-Grundkenntnisse
  • ✅ SQL-Grundkenntnisse

Erster Tag?
Perfekt! Wir starten gemeinsam von Grund auf. Ich erkläre dir alles Schritt für Schritt.

Setup-Probleme?
Am Ende dieses Posts findest du eine ausführliche Troubleshooting-Sektion.


⚡ Das Wichtigste in 30 Sekunden

Heute lernst du:

  • ✅ Was Java EE ist und welche Komponenten es beinhaltet
  • ✅ Den Unterschied zwischen Java SE und Java EE
  • ✅ Was ein Application Server ist und welche Aufgaben er hat
  • ✅ Was ein Webcontainer ist und wie er funktioniert
  • ✅ Das Client-Server-Modell im Web-Kontext
  • ✅ Grundlagen des HTTP-Protokolls
  • ✅ Payara Server in NetBeans einrichten

Am Ende des Tages kannst du:

  • Die Architektur einer Java Webanwendung erklären
  • Einen Application Server (Payara) in NetBeans konfigurieren
  • Die Rolle des Webcontainers verstehen
  • Erklären, warum wir einen Application Server brauchen

Zeit-Investment: ~8 Stunden
Schwierigkeitsgrad: Anfänger (aber fordernd!)


👋 Willkommen bei Java Web Basic!

Hi! 👋

Elyndra hier. Willkommen zu Tag 1 unseres 10-tägigen Java Web Basic Kurses und der begint mit den Java EE Grundlagen!

Warum Java EE wichtig ist:

Wenn du bisher nur mit Java SE gearbeitet hast – Konsolen-Anwendungen, vielleicht Desktop-Programme mit Swing oder JavaFX – dann betrittst du heute eine komplett neue Welt: die Welt der Enterprise-Webanwendungen.

Und ich sage dir direkt: Es wird am Anfang überwältigend sein. Das ist vollkommen normal.

Als ich damals meine erste Java EE Anwendung gebaut habe, habe ich mich gefragt: „Warum ist das alles so kompliziert? Warum kann ich nicht einfach eine main()-Methode schreiben wie in Java SE?“

Die Antwort habe ich erst später verstanden: Es geht nicht darum, dass Java EE kompliziert ist – es ist einfach ein anderes Paradigma. Statt Programme zu schreiben, die von Anfang bis Ende durchlaufen, bauen wir Komponenten, die auf Anfragen reagieren.

Ein Vergleich aus meiner Welt:

Stell dir vor, Java SE ist wie ein Werkzeug, das du direkt in der Hand hältst – ein Hammer, eine Säge. Du steuerst jede Bewegung selbst.

Java EE ist wie eine Werkstatt mit Maschinen: Eine Drehbank, eine Fräsmaschine. Du gibst die Parameter ein, drückst auf Start, und die Maschine arbeitet nach einem festgelegten Prozess. Du steuerst nicht jeden Schritt selbst, aber du konfigurierst, WAS gemacht werden soll.

Der Application Server ist diese Werkstatt. Und heute lernst du, wie du diese Werkstatt einrichtest und verstehst.

Was dich heute erwartet:

Wir werden heute viel Theorie machen. Ich weiß, das klingt nicht aufregend. Aber glaub mir: Ohne dieses Fundament wirst du später bei Servlets, JSPs und Frameworks wie Spring Boot nur Bahnhof verstehen.

Wir schauen uns an:

  1. Was Java EE überhaupt ist
  2. Wie das Client-Server-Modell funktioniert
  3. Was ein Application Server macht
  4. Was ein Webcontainer ist
  5. Wie HTTP funktioniert (das Protokoll, das ALLES im Web antreibt)

Und dann – ganz wichtig – richten wir zusammen Payara Server in NetBeans ein. Hands-on!

Keine Sorge:

Auch wenn heute viel Theorie dabei ist – ich erkläre dir alles in mehreren Schichten. Erst das „Was“, dann das „Wie“, dann das „Warum“. So wie ich es selbst gerne lerne.

Und denk dran: Bei meinem Fachwerkhaus musste ich auch erst die Statik verstehen, bevor ich renovieren konnte. Sonst hätte ich tragende Balken entfernt und das ganze Haus wäre zusammengefallen.

Genauso ist es mit Java EE – erst verstehen, dann bauen.

Los geht’s! 🔧


🟢 GRUNDLAGEN: Was ist Java EE?

Java SE vs. Java EE – Der fundamentale Unterschied

Java SE kennst du bereits:

Java Standard Edition (SE) ist das, was du bisher verwendet hast. Es beinhaltet:

// Typisches Java SE Programm
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
        
        // Collections
        List<String> names = new ArrayList<>();
        names.add("Anna");
        names.add("Ben");
        
        // File I/O
        try (BufferedReader reader = new BufferedReader(
                new FileReader("data.txt"))) {
            String line = reader.readLine();
        }
        
        // JDBC für Datenbanken
        Connection conn = DriverManager.getConnection(url, user, password);
    }
}

Was macht dieser Code?

Das ist ein klassisches Java SE Programm. Es hat einen klaren Einstiegspunkt (main()-Methode), läuft linear von oben nach unten durch, und wenn es fertig ist, terminiert das Programm.

Das Problem mit Java SE für Webanwendungen:

Stell dir vor, du willst einen Webshop bauen:

  • Tausende Benutzer greifen gleichzeitig zu
  • Jeder macht etwas anderes (einer browst, einer legt Artikel in den Warenkorb, einer bezahlt)
  • Die Anwendung muss 24/7 laufen
  • Datenbank-Verbindungen müssen effizient verwaltet werden
  • Sicherheit, Transaktionen, Sessions müssen gemanagt werden

Mit Java SE müsstest du all das selbst implementieren:

  • Thread-Management für tausende gleichzeitige Anfragen
  • Connection Pooling für Datenbankverbindungen
  • Session-Management
  • Security
  • Transaction-Management
  • Und vieles mehr…

Das wäre ein Albtraum!


Java EE – Enterprise Edition

Was ist Java EE?

Java EE (Enterprise Edition) ist eine Sammlung von Spezifikationen und APIs, die auf Java SE aufbauen und speziell für Enterprise-Anwendungen entwickelt wurden.

Wichtig zu verstehen:

Java EE ist KEINE neue Programmiersprache! Es ist auch kein eigenständiges Framework. Es ist ein Standard – eine Sammlung von Spezifikationen, die beschreiben, wie bestimmte Enterprise-Funktionalitäten implementiert werden sollen.

Die wichtigsten Java EE Komponenten (für uns relevant):

  1. Servlets – Java-Klassen, die HTTP-Requests verarbeiten
  2. JSP (JavaServer Pages) – HTML mit eingebettetem Java-Code
  3. JSTL (JSP Standard Tag Library) – Tag-Bibliotheken für JSPs
  4. Expression Language (EL) – Vereinfachte Syntax für Datenzugriff in JSPs
  5. JDBC – Datenbankzugriff (kennst du aus Java SE, aber in EE erweitert)
  6. JPA (Java Persistence API) – ORM für Datenbanken (kommt später)
  7. CDI (Contexts and Dependency Injection) – Dependency Injection
  8. JAX-RS – REST-Services (kommt später)

Für diesen Kurs fokussieren wir uns auf:

  • Servlets
  • JSP
  • JSTL
  • Expression Language
  • JDBC im Web-Kontext

Was macht dieser Java EE Standard?

Der Standard definiert:

  1. Interfaces und APIs – Wie die Komponenten aussehen müssen
  2. Verhalten – Wie sie sich verhalten sollen
  3. Deployment – Wie sie deployed werden
  4. Lifecycle – Wie sie vom Container verwaltet werden

Aber:

Der Standard sagt NICHT, WIE das implementiert wird. Das machen die Application Server.


Application Server – Die Implementierung des Standards

Was ist ein Application Server?

Ein Application Server ist eine Software, die den Java EE Standard implementiert. Er stellt die Laufzeitumgebung für Java EE Anwendungen bereit.

Bekannte Application Server:

  • Payara Server (den wir verwenden!) – Fork von GlassFish
  • WildFly (ehemals JBoss) – von Red Hat
  • GlassFish – Referenzimplementierung (aber nicht mehr aktiv entwickelt)
  • WebLogic – von Oracle (kommerziell)
  • WebSphere – von IBM (kommerziell)
  • TomEE – Tomcat + Java EE Features

Warum verwenden wir Payara?

Payara ist:

  • Open Source
  • Aktiv entwickelt
  • Produktionsreif
  • Gut dokumentiert
  • Einfach zu bedienen
  • Kompatibel mit NetBeans

Wichtig zu verstehen:

Der Application Server ist NICHT deine Anwendung. Er ist die Plattform, auf der deine Anwendung läuft.

Vergleich: Deine Java EE Anwendung ist wie ein Programm. Der Application Server ist wie das Betriebssystem, auf dem das Programm läuft.


Was macht ein Application Server? (Im Detail!)

Der Application Server übernimmt für dich:

1. Webcontainer / Servlet Container

Der Webcontainer ist eine Komponente des Application Servers, die speziell für Web-Anwendungen zuständig ist.

Er managed:

  • HTTP-Requests und -Responses
  • Servlets und JSPs
  • Session-Management
  • URL-Mapping

Wie funktioniert das?

Browser                  Payara Server
  |                            |
  |------ HTTP Request ------->|
  |                            |
  |                       Webcontainer
  |                            |
  |                       empfängt Request
  |                            |
  |                       findet passendes Servlet
  |                            |
  |                       ruft Servlet auf
  |                            |
  |                       Servlet generiert Response
  |                            |
  |<----- HTTP Response -------|
  |                            |

Wichtig:

Du schreibst NICHT den Code, der auf Port 8080 lauscht. Du schreibst NICHT den Code, der HTTP-Requests parst. Du schreibst NICHT den Code, der Threads verwaltet.

Das macht alles der Webcontainer!

Du schreibst nur: „Was soll passieren, wenn ein Request kommt?“


2. Lifecycle-Management

Der Application Server verwaltet den Lebenszyklus deiner Komponenten.

Beispiel Servlet:

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    
    @Override
    public void init() {
        // Server ruft diese Methode beim Start auf
        System.out.println("Servlet wird initialisiert");
    }
    
    @Override
    protected void doGet(HttpServletRequest request, 
                        HttpServletResponse response) {
        // Server ruft diese Methode bei jedem GET-Request auf
    }
    
    @Override
    public void destroy() {
        // Server ruft diese Methode beim Herunterfahren auf
        System.out.println("Servlet wird zerstört");
    }
}

Was passiert hier?

  1. Beim Deployment erstellt der Server EINE Instanz des Servlets
  2. Er ruft init() auf
  3. Bei jedem Request ruft er doGet() oder doPost() auf (im selben Thread)
  4. Beim Shutdown ruft er destroy() auf

Du musst dich um NICHTS davon kümmern!

Der Application Server macht das alles automatisch.


3. Connection Pooling

Ohne Application Server:

// Bei jedem Request eine neue DB-Verbindung (SCHLECHT!)
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
    Connection conn = DriverManager.getConnection(url, user, pwd);
    // ... Datenbankarbeit
    conn.close();
}

Problem:

  • Jede DB-Verbindung dauert 50-200ms
  • Bei 1000 Requests/Sekunde = 50.000-200.000ms nur für Verbindungsaufbau!
  • Das ist ineffizient und langsam

Mit Application Server:

// Hole Verbindung aus dem Pool (SCHNELL!)
@Resource(name = "jdbc/mydb")
private DataSource dataSource;

public void doGet(HttpServletRequest req, HttpServletResponse resp) {
    Connection conn = dataSource.getConnection(); // <-- aus Pool!
    // ... Datenbankarbeit
    conn.close(); // gibt Verbindung zurück in Pool
}

Was macht der Application Server?

  1. Beim Start erstellt er z.B. 20 Datenbankverbindungen
  2. Diese Verbindungen bleiben offen (im „Pool“)
  3. Deine Anwendung „leiht“ sich eine Verbindung aus dem Pool
  4. Nach Benutzung gibst du sie zurück
  5. Nächster Request kann sie wiederverwenden

Vorteil: Keine Zeit für Verbindungsaufbau! Viel schneller!


4. Threading & Concurrent Request Handling

Ohne Application Server müsstest du schreiben:

// DAS musst du NICHT schreiben! (zum Glück!)
ServerSocket serverSocket = new ServerSocket(8080);

while (true) {
    Socket clientSocket = serverSocket.accept();
    
    // Für jeden Request einen neuen Thread erstellen
    Thread thread = new Thread(() -> {
        // Request lesen
        // Verarbeiten
        // Response schreiben
    });
    thread.start();
}

Mit Application Server:

Du schreibst einfach:

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        // Deine Business-Logik
    }
}

Der Application Server:

  • Managed einen Thread-Pool
  • Weist jedem Request automatisch einen Thread zu
  • Kümmert sich um Thread-Safety (teilweise)
  • Räumt nach Request-Ende auf

5. Security

Der Application Server bietet:

  • Authentication (Wer bist du?)
  • Authorization (Was darfst du?)
  • Verschlüsselung (HTTPS)
  • Protection gegen common Attacks

Beispiel:

@WebServlet("/admin")
@ServletSecurity(
    @HttpConstraint(rolesAllowed = "admin")
)
public class AdminServlet extends HttpServlet {
    // Nur für User mit "admin"-Rolle zugänglich
}

Der Application Server prüft das automatisch!


6. Transaction Management

Bei komplexen Operationen über mehrere Datenbanktabellen:

@Transactional
public void transferMoney(Account from, Account to, BigDecimal amount) {
    from.withdraw(amount);  // Schritt 1
    to.deposit(amount);     // Schritt 2
}

Der Application Server garantiert:

  • Entweder BEIDE Schritte passieren
  • Oder KEINER passiert (Rollback)
  • Keine inkonsistenten Zustände

Zusammenfassung: Was ist ein Application Server?

Ein Application Server ist eine Middleware-Plattform, die:

  1. Die Java EE Spezifikationen implementiert
  2. Eine Laufzeitumgebung bereitstellt für deine Komponenten
  3. Services bereitstellt (Threading, Pooling, Security, Transactions)
  4. Deine Komponenten verwaltet (Lifecycle, Dependency Injection)
  5. HTTP-Requests verarbeitet (via Webcontainer)

Du konzentrierst dich auf die Business-Logik, der Server kümmert sich um den Rest!


🟡 PROFESSIONALS: Der Webcontainer im Detail

Was ist ein Webcontainer?

Definition:

Der Webcontainer (auch „Servlet Container“ genannt) ist eine Komponente des Application Servers, die speziell für die Ausführung von Servlets und JSPs zuständig ist.

Wichtig zu verstehen:

Der Webcontainer ist TEIL des Application Servers. Nicht jeder Application Server braucht einen Webcontainer – manche Server sind nur für EJBs (Enterprise JavaBeans) zuständig. Aber für Webanwendungen brauchst du einen Webcontainer.

Bekannte Webcontainer:

  • Payara Server – Full Application Server mit Webcontainer
  • Apache Tomcat – NUR Webcontainer (kein vollständiger Application Server!)
  • Jetty – Leichtgewichtiger Webcontainer

Der Unterschied:

  • Tomcat = Nur Webcontainer (Servlets + JSPs)
  • Payara = Full Application Server (Servlets + JSPs + EJB + JPA + CDI + JAX-RS + …)

Für diesen Kurs verwenden wir Payara, weil wir später auch mit JPA arbeiten werden.


Was macht der Webcontainer? (Technisch!)

Phase 1: Startup

Beim Start des Application Servers:

1. Webcontainer startet
2. Scannt nach Web-Applikationen (WAR-Files)
3. Liest die Deployment Descriptors (web.xml)
4. Initialisiert Servlets (lazy oder eager)
5. Macht die App verfügbar unter URL

Phase 2: Request Handling

Wenn ein HTTP-Request ankommt:

Client                    Webcontainer                Servlet
  |                             |                         |
  |---- HTTP GET /hello ------> |                         |
  |                             |                         |
  |                        [1] Request parsen             |
  |                             |                         |
  |                        [2] Passenden Servlet finden   |
  |                             |                         |
  |                        [3] HttpServletRequest         |
  |                             |   erstellen             |
  |                             |                         |
  |                        [4] HttpServletResponse        |
  |                             |   erstellen             |
  |                             |                         |
  |                             |---- doGet() ----------->|
  |                             |                         |
  |                             |                    [5] Verarbeiten
  |                             |                         |
  |                             |<---- Response Data -----|
  |                             |                         |
  |                        [6] Response in HTTP           |
  |                             |   formatieren           |
  |                             |                         |
  |<---- HTTP Response 200 ---- |                         |
  |                             |                         |

Schauen wir uns jeden Schritt genauer an:

Schritt 1: Request Parsen

Der Webcontainer liest den rohen HTTP-Request:

GET /hello?name=Anna HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0
Accept: text/html
Cookie: JSESSIONID=ABC123

Und parsed das in strukturierte Daten:

  • Method: GET
  • Path: /hello
  • Query Parameter: name=Anna
  • Headers: Host, User-Agent, Accept
  • Cookies: JSESSIONID=ABC123

Schritt 2: Servlet Mapping

Der Webcontainer schaut nach: „Welches Servlet ist für /hello zuständig?“

Das steht entweder:

  • In der web.xml (Deployment Descriptor)
  • Oder in Annotations (@WebServlet("/hello"))

Schritt 3: HttpServletRequest erstellen

Der Webcontainer erstellt ein Objekt mit allen Request-Infos:

HttpServletRequest request = new HttpServletRequestWrapper() {
    // Alle Request-Daten sind hier drin:
    public String getParameter(String name) {
        // Bei /hello?name=Anna
        // request.getParameter("name") gibt "Anna" zurück
    }
    
    public String getHeader(String name) {
        // request.getHeader("User-Agent") gibt "Mozilla/5.0" zurück
    }
    
    public HttpSession getSession() {
        // Gibt Session-Objekt zurück (Cookie-basiert)
    }
};

Schritt 4: HttpServletResponse erstellen

Der Webcontainer erstellt auch ein Response-Objekt:

HttpServletResponse response = new HttpServletResponseWrapper() {
    public void setContentType(String type) {
        // Setzt Content-Type Header
    }
    
    public PrintWriter getWriter() {
        // Gibt Writer für Response-Body zurück
    }
    
    public void setStatus(int sc) {
        // Setzt HTTP Status Code (200, 404, 500, etc.)
    }
};

Schritt 5: Servlet aufrufen

Der Webcontainer ruft dein Servlet auf:

// DAS ist der Code, den DU schreibst:
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, 
                        HttpServletResponse response) 
                        throws IOException {
        
        String name = request.getParameter("name"); // "Anna"
        
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<h1>Hello, " + name + "!</h1>");
    }
}

Schritt 6: Response formatieren

Der Webcontainer nimmt deine Ausgabe und baut einen HTTP-Response:

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 25
Date: Sat, 25 Oct 2025 10:00:00 GMT
Server: Payara Server 6.0

<h1>Hello, Anna!</h1>

Und schickt das zurück an den Browser!


Servlet Lifecycle im Detail

Wichtig zu verstehen:

Ein Servlet ist NICHT wie eine normale Klasse. Der Webcontainer verwaltet es nach einem fest definierten Lifecycle.

Der Lifecycle:

[1] Loading & Instantiation
       ↓
[2] Initialization - init()
       ↓
[3] Request Handling - service() → doGet() / doPost()
       ↓  (Wird für jeden Request aufgerufen!)
       ↓
[4] Destruction - destroy()

Phase 1: Loading & Instantiation

Beim Deployment (oder beim ersten Request):

// Webcontainer macht:
HelloServlet servlet = new HelloServlet();

Wichtig:

  • Es wird NUR EINE Instanz erstellt!
  • Diese eine Instanz verarbeitet ALLE Requests!
  • Das heißt: Multiple Threads können gleichzeitig auf das gleiche Servlet-Objekt zugreifen!

Phase 2: Initialization

Nach der Instanziierung:

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    
    private DatabaseConnection dbConn;
    
    @Override
    public void init() throws ServletException {
        // Wird EINMAL beim Start aufgerufen
        System.out.println("Servlet wird initialisiert");
        
        // Initialisiere teure Ressourcen hier
        dbConn = new DatabaseConnection();
    }
}

Wofür ist init() gut?

Für Ressourcen, die du NUR EINMAL brauchst:

  • Datenbankverbindungen aufbauen
  • Konfigurationsdateien laden
  • Caches initialisieren

Phase 3: Request Handling

Für JEDEN Request wird aufgerufen:

protected void doGet(HttpServletRequest request, 
                    HttpServletResponse response) {
    // Wird bei JEDEM GET-Request aufgerufen
    // Kann parallel in mehreren Threads laufen!
}

Wichtig:

  • Jeder Request läuft in seinem eigenen Thread
  • Aber alle Threads nutzen die GLEICHE Servlet-Instanz
  • Deshalb: Vorsicht mit Instanzvariablen!

Gefahr – Thread Safety:

@WebServlet("/counter")
public class CounterServlet extends HttpServlet {
    
    private int counter = 0; // GEFAHR! Shared State!
    
    protected void doGet(HttpServletRequest request, 
                        HttpServletResponse response) {
        counter++; // NICHT Thread-Safe!
        response.getWriter().println("Count: " + counter);
    }
}

Problem:

Wenn 2 Requests gleichzeitig kommen:

Thread 1: liest counter = 0
Thread 2: liest counter = 0
Thread 1: counter++ → 1
Thread 2: counter++ → 1  (sollte 2 sein!)

Lösung:

Entweder:

  • Keine Instanzvariablen für Request-spezifische Daten
  • Oder: synchronized verwenden (aber schlecht für Performance)
  • Oder: ThreadLocal verwenden

Phase 4: Destruction

Beim Herunterfahren des Servers:

@Override
public void destroy() {
    // Wird beim Shutdown aufgerufen
    System.out.println("Servlet wird zerstört");
    
    // Räume Ressourcen auf
    dbConn.close();
}

🟢 GRUNDLAGEN: Das Client-Server-Modell

Was ist das Client-Server-Modell?

Definition:

Das Client-Server-Modell ist ein Architekturmuster, bei dem Aufgaben zwischen Clients (Anfragenden) und Servern (Anbietenden) aufgeteilt werden.

Im Web-Kontext:

  • Client = Browser (Chrome, Firefox, Safari, etc.)
  • Server = Webserver + Application Server (z.B. Payara mit deiner Java App)

Kommunikation:

Client (Browser)              Server (Payara + deine App)
     |                                    |
     |-------- Request ------------------>|
     |  "Gib mir die Startseite"          |
     |                                    |
     |                          [Verarbeitung]
     |                                    |
     |<------- Response ------------------|
     |  "Hier ist die HTML-Seite"         |
     |                                    |

Charakteristika des Client-Server-Modells

1. Klare Rollentrennung

Client:

  • Initiiert die Kommunikation
  • Sendet Requests
  • Rendert die Response (zeigt HTML/CSS an)
  • Führt JavaScript aus

Server:

  • Wartet auf Requests
  • Verarbeitet Requests
  • Generiert Responses
  • Verwaltet Daten

2. Viele Clients, ein Server

Browser 1 ----\
               \
Browser 2 -----|---> Payara Server --> Deine Java App
               /
Browser 3 ----/

Ein Server bedient viele Clients gleichzeitig.

3. Zustandslos (Stateless)

Wichtig:

HTTP ist zustandslos! Das bedeutet:

Request 1: "Zeig mir Produkt A"
Request 2: "Zeig mir Produkt B"

Der Server „erinnert sich nicht“ an Request 1 wenn Request 2 kommt!

Problem:

Aber wir BRAUCHEN doch Zustände! Beispiel Webshop:

Request 1: Login als "anna@example.com"
Request 2: Lege Produkt A in Warenkorb
Request 3: Lege Produkt B in Warenkorb
Request 4: Checkout

Der Server muss wissen:

  • Wer ist der User? (aus Request 1)
  • Was ist im Warenkorb? (aus Request 2 & 3)

Lösung: Sessions

Der Server speichert Zustand in einer Session:

Client                          Server
  |                               |
  |---- Login (anna) ------------>| Erstellt Session: ID=ABC123
  |<---- Set-Cookie: ABC123 ------|
  |                               | Speichert: ABC123 → User: Anna
  |                               |
  |---- Produkt A (Cookie: ABC123)|
  |                               | Liest Session ABC123 → Anna
  |                               | Speichert: ABC123 → Warenkorb: [A]
  |                               |
  |---- Produkt B (Cookie: ABC123)|
  |                               | Liest Session ABC123 → Anna
  |                               | Speichert: ABC123 → Warenkorb: [A, B]

Wie funktioniert das technisch?

  1. Server erstellt eine Session-ID (z.B. „ABC123“)
  2. Schickt die ID als Cookie an den Browser
  3. Browser sendet den Cookie bei jedem weiteren Request mit
  4. Server erkennt anhand der ID: „Ah, das ist Anna!“

In Java:

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, 
                         HttpServletResponse response) {
        String email = request.getParameter("email");
        
        // Session erstellen oder holen
        HttpSession session = request.getSession();
        
        // Daten in Session speichern
        session.setAttribute("user", email);
        
        // Ab jetzt: Alle Requests mit diesem Cookie
        // können auf die Session zugreifen!
    }
}

@WebServlet("/cart")
public class CartServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, 
                        HttpServletResponse response) {
        // Session holen (automatisch via Cookie!)
        HttpSession session = request.getSession();
        
        // Daten aus Session lesen
        String user = (String) session.getAttribute("user");
        // user = "anna@example.com"
    }
}

Der Webcontainer macht das automatisch!

Du musst dich NICHT um Cookies kümmern. Du rufst einfach request.getSession() auf, und der Webcontainer:

  1. Liest den Cookie
  2. Findet die passende Session
  3. Gibt dir das Session-Objekt zurück

🟢 GRUNDLAGEN: Das HTTP-Protokoll

Was ist HTTP?

HTTP = HyperText Transfer Protocol

HTTP ist das Protokoll, das im Web verwendet wird, um Daten zwischen Client und Server auszutauschen.

Wichtig zu verstehen:

HTTP ist ein Text-basiertes Protokoll. Alles, was zwischen Browser und Server ausgetauscht wird, ist letztendlich Text (bzw. Bytes, die als Text interpretiert werden können).


Anatomie eines HTTP-Requests

Beispiel:

Wenn du in deinem Browser http://localhost:8080/hello?name=Anna eingibst, schickt der Browser diesen HTTP-Request:

GET /hello?name=Anna HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: JSESSIONID=ABC123

Aufbau:

[1] Request Line
[2] Headers
[3] Empty Line
[4] Body (optional)

[1] Request Line

GET /hello?name=Anna HTTP/1.1

Besteht aus:

  • Method: GET
  • Path: /hello?name=Anna
  • Protocol Version: HTTP/1.1

[2] Headers

Host: localhost:8080
User-Agent: Mozilla/5.0 ...
Accept: text/html ...
Cookie: JSESSIONID=ABC123

Headers sind Metadaten über den Request:

  • Host: Zu welchem Server geht der Request
  • User-Agent: Welcher Browser wird verwendet
  • Accept: Welche Content-Types akzeptiert der Browser
  • Cookie: Session-Cookie

[3] Empty Line

Eine leere Zeile trennt Headers vom Body.

[4] Body (bei POST/PUT)

Bei GET-Requests gibt es keinen Body.

Bei POST-Requests schon:

POST /login HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
Content-Length: 33

email=anna@example.com&password=123

Anatomie einer HTTP-Response

Nachdem der Server den Request verarbeitet hat, schickt er eine Response:

HTTP/1.1 200 OK
Date: Sat, 25 Oct 2025 10:00:00 GMT
Server: Payara Server 6.0.0
Content-Type: text/html;charset=UTF-8
Content-Length: 145
Set-Cookie: JSESSIONID=ABC123; Path=/; HttpOnly

<!DOCTYPE html>
<html>
<head>
    <title>Hello</title>
</head>
<body>
    <h1>Hello, Anna!</h1>
</body>
</html>

Aufbau:

[1] Status Line
[2] Headers
[3] Empty Line
[4] Body

[1] Status Line

HTTP/1.1 200 OK

Besteht aus:

  • Protocol Version: HTTP/1.1
  • Status Code: 200
  • Reason Phrase: OK

[2] Headers

Date: Sat, 25 Oct 2025 10:00:00 GMT
Server: Payara Server 6.0.0
Content-Type: text/html;charset=UTF-8
Set-Cookie: JSESSIONID=ABC123; Path=/; HttpOnly

[3] Empty Line

Trennt Headers vom Body.

[4] Body

<!DOCTYPE html>
<html>
...
</html>

Das ist das, was der Browser anzeigt!


HTTP-Methoden (Verben)

Die wichtigsten HTTP-Methoden:

MethodeZweckHat Body?Idempotent?
GETDaten abrufenNeinJa
POSTDaten senden / Ressource erstellenJaNein
PUTRessource ersetzenJaJa
DELETERessource löschenNeinJa
PATCHRessource teilweise ändernJaNein
HEADWie GET, aber nur HeadersNeinJa
OPTIONSZeigt erlaubte MethodenNeinJa

Für diesen Kurs fokussieren wir uns auf:

  • GET – Daten abrufen
  • POST – Formulare absenden

GET vs. POST – Der Unterschied

GET-Request

Verwendung:

  • Daten abrufen
  • Bookmarkable URLs
  • Keine sensiblen Daten

Beispiel:

GET /products?category=electronics&sort=price HTTP/1.1

Charakteristika:

  • Parameter in der URL
  • Kein Request Body
  • Kann gecached werden
  • Kann bookmarked werden
  • Sichtbar in Browser-History

In Java:

@WebServlet("/products")
public class ProductServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, 
                        HttpServletResponse response) {
        String category = request.getParameter("category");
        String sort = request.getParameter("sort");
        
        // category = "electronics"
        // sort = "price"
    }
}

POST-Request

Verwendung:

  • Formulare absenden
  • Daten erstellen/ändern
  • Sensible Daten (Passwörter!)

Beispiel:

POST /login HTTP/1.1
Content-Type: application/x-www-form-urlencoded

email=anna@example.com&password=secret123

Charakteristika:

  • Parameter im Request Body
  • Nicht in URL sichtbar
  • Wird nicht gecached
  • Nicht bookmarkable

In Java:

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, 
                         HttpServletResponse response) {
        String email = request.getParameter("email");
        String password = request.getParameter("password");
        
        // Passwort ist NICHT in der URL!
    }
}

Wichtig:

Für Login-Formulare IMMER POST verwenden, nicht GET!

<!-- FALSCH! -->
<form action="/login" method="get">
  <!-- Passwort landet in URL: /login?email=...&password=secret123 -->
</form>

<!-- RICHTIG! -->
<form action="/login" method="post">
  <!-- Passwort im Request Body, nicht in URL -->
</form>

HTTP-Status-Codes

Der Server antwortet immer mit einem Status-Code:

2xx – Success

CodeBedeutungVerwendung
200OKErfolgreich
201CreatedRessource erstellt
204No ContentErfolgreich, aber keine Daten

3xx – Redirection

CodeBedeutungVerwendung
301Moved PermanentlyPermanente Weiterleitung
302FoundTemporäre Weiterleitung
304Not ModifiedCached Version ist aktuell

4xx – Client Error

CodeBedeutungVerwendung
400Bad RequestFehlerhafte Anfrage
401UnauthorizedNicht authentifiziert
403ForbiddenNicht autorisiert
404Not FoundRessource existiert nicht

5xx – Server Error

CodeBedeutungVerwendung
500Internal Server ErrorServer-Fehler
502Bad GatewayGateway-Fehler
503Service UnavailableServer überlastet

In Java setzen:

@WebServlet("/products")
public class ProductServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, 
                        HttpServletResponse response) {
        String id = request.getParameter("id");
        
        Product product = database.findProduct(id);
        
        if (product == null) {
            // 404 - Not Found
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            response.getWriter().println("Product not found");
        } else {
            // 200 - OK (default)
            response.getWriter().println(product.toHTML());
        }
    }
}

Content-Type Header

Wichtig:

Der Content-Type Header sagt dem Browser, WAS für Daten gesendet werden.

Häufige Content-Types:

Content-TypeBedeutung
text/htmlHTML-Seite
text/plainPlain Text
application/jsonJSON-Daten
application/xmlXML-Daten
application/pdfPDF-Dokument
image/pngPNG-Bild
image/jpegJPEG-Bild

In Java:

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, 
                        HttpServletResponse response) 
                        throws IOException {
        
        // WICHTIG: IMMER Content-Type setzen!
        response.setContentType("text/html;charset=UTF-8");
        
        PrintWriter out = response.getWriter();
        out.println("<h1>Hello World!</h1>");
    }
}

Warum ist das wichtig?

Ohne Content-Type: text/html weiß der Browser nicht, dass es sich um HTML handelt, und zeigt eventuell nur den Quelltext an!


🔵 BONUS: HTTPS – Sicheres HTTP

Was ist HTTPS?

HTTPS = HTTP + SSL/TLS

HTTPS ist HTTP mit Verschlüsselung. Alle Daten zwischen Client und Server werden verschlüsselt übertragen.

Ohne HTTPS (HTTP):

Browser --> [Klartext] --> Router --> [Klartext] --> Server

Jeder auf dem Weg kann mitlesen:

  • Dein Internet-Provider
  • Dein Arbeitgeber (im Firmen-Netzwerk)
  • Hacker im gleichen WLAN

Mit HTTPS:

Browser --> [Verschlüsselt] --> Router --> [Verschlüsselt] --> Server

Niemand kann die Daten mitlesen!

Wofür brauchst du HTTPS?

  • Login-Formulare (Passwörter!)
  • Checkout (Kreditkarten!)
  • Jede Seite mit persönlichen Daten
  • Eigentlich: Überall!

Moderne Browser warnen bei HTTP-Seiten: „Nicht sicher“

Wie aktiviert man HTTPS in Payara?

Das schauen wir uns in einem späteren Tag an, wenn wir Deployment behandeln.


🟡 PROFESSIONALS: Payara Server in NetBeans einrichten

Payara Server herunterladen

Schritt 1: Payara herunterladen

Gehe zu: https://www.payara.fish/downloads/

Wähle:

  • Payara Server Full
  • Version 6.x (Latest Stable)
  • Download als ZIP

Schritt 2: Entpacken

Entpacke das ZIP an einen Ort OHNE Leerzeichen im Pfad!

Gut:

  • C:\payara6
  • C:\dev\payara6
  • /opt/payara6

Schlecht:

  • C:\Program Files\Payara (Leerzeichen!)
  • C:\Meine Dokumente\Payara (Leerzeichen + Umlaute!)

Payara in NetBeans einrichten

Schritt 1: NetBeans öffnen

Starte Apache NetBeans 22.

Schritt 2: Services-Tab öffnen

Window → Services

Oder: Strg + 5

Schritt 3: Server hinzufügen

Im Services-Tab:

Servers → Rechtsklick → Add Server...

Schritt 4: Server-Typ wählen

Wähle:

  • Payara Server

Falls „Payara Server“ nicht auftaucht:

Tools → Plugins → Available Plugins
→ Suche nach "Payara"
→ Installiere "Payara Server Tools"
→ Restart NetBeans

Schritt 5: Server-Location angeben

Server Location: C:\payara6\glassfish

(Ja, der Ordner heißt „glassfish“, weil Payara ein GlassFish-Fork ist!)

Schritt 6: Domain-Name

Domain Name: domain1

(Das ist die Standard-Domain)

Schritt 7: Admin-Credentials

Username: admin
Password: (leer lassen)

(Ja, wirklich leer! Für lokale Entwicklung okay.)

Schritt 8: Fertig!

Klicke auf Finish.


Payara Server starten

Im Services-Tab:

Servers → Payara Server → Rechtsklick → Start

Oder:

Servers → Payara Server → Grüner Play-Button

Was passiert jetzt?

NetBeans startet Payara im Hintergrund. Im Output-Tab siehst du:

Launching Payara Server...
Starting domain domain1
Domain domain1 started
Payara Server is running.
Server startup in 3420 ms

Admin-Console öffnen:

Payara läuft jetzt auf:

Öffne http://localhost:4848 im Browser.

Du siehst:

Die Payara Admin Console – ein Web-Interface, um den Server zu verwalten.


Erstes Test-Projekt erstellen

Schritt 1: Neues Projekt

File → New Project...

Schritt 2: Projekt-Typ wählen

Categories: Java with Maven
Projects: Web Application

Klicke Next.

Schritt 3: Projekt-Name

Project Name: HelloPayara
Project Location: C:\dev\projects
Group Id: com.javafleet

Klicke Next.

Schritt 4: Server wählen

Server: Payara Server
Java EE Version: Jakarta EE 10 Web

Klicke Finish.


Struktur des Projekts

NetBeans erstellt diese Struktur:

HelloPayara/
├── pom.xml (Maven Configuration)
├── src/
│   └── main/
│       ├── java/ (Deine Servlets kommen hier rein)
│       └── webapp/
│           ├── WEB-INF/
│           │   └── web.xml (Deployment Descriptor)
│           └── index.html (Startseite)
└── target/ (Compiled Classes - wird von Maven generiert)

Was ist was?

  • pom.xml: Maven Build-Konfiguration (Dependencies, Plugins)
  • src/main/java: Deine Java-Klassen (Servlets, POJOs, etc.)
  • src/main/webapp: Web-Content (HTML, JSP, CSS, JavaScript)
  • WEB-INF/web.xml: Deployment Descriptor (Konfiguration der App)
  • target/: Compiled Output (nach Build)

Erste Seite testen

Schritt 1: index.html öffnen

Öffne src/main/webapp/index.html.

NetBeans hat bereits eine Test-Seite erstellt:

<!DOCTYPE html>
<html>
    <head>
        <title>Start Page</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <h1>Hello World!</h1>
    </body>
</html>

Schritt 2: Projekt deployen

Rechtsklick auf das Projekt → Run

Oder: F6

Was passiert?

  1. Maven baut das Projekt (kompiliert Java-Code)
  2. Erstellt ein WAR-File (Web ARchive)
  3. Deployed das WAR auf Payara
  4. Startet deinen Browser mit http://localhost:8080/HelloPayara/

Du siehst:

Hello World!

Glückwunsch! 🎉

Deine erste Java EE Anwendung läuft!


Was ist gerade passiert? (Im Detail!)

Schritt-für-Schritt:

  1. Maven Build

Maven hat dein Projekt gebaut:

[INFO] Building war: C:\dev\projects\HelloPayara\target\HelloPayara.war
  1. WAR-File Struktur

Das WAR-File sieht so aus:

HelloPayara.war
├── index.html
├── WEB-INF/
│   ├── web.xml
│   └── classes/ (Compiled .class files)
└── META-INF/
    └── MANIFEST.MF
  1. Deployment

NetBeans hat das WAR auf Payara deployed:

Deploying HelloPayara.war to Payara Server
Deployment successful
Application deployed at: http://localhost:8080/HelloPayara
  1. Webcontainer

Der Payara Webcontainer:

  1. Browser-Request

Dein Browser hat gesendet:

GET /HelloPayara/ HTTP/1.1
Host: localhost:8080
  1. Payara-Response

Payara hat geantwortet:

HTTP/1.1 200 OK
Content-Type: text/html

<!DOCTYPE html>
<html>
...
</html>

Das ist der komplette Zyklus!


💬 Real Talk: Mittagspause-Gespräch

Java Fleet Küche, 12:45 Uhr. Elyndra holt sich einen Kaffee, Nova sitzt mit ihrem Laptop am Tisch, Cassian macht sich ein Sandwich.


Nova: „Elyndra, ehrliche Frage: Warum ist Java EE eigentlich so komplex? Bei Spring Boot mache ich @SpringBootApplication und es läuft. Hier muss ich Application Server konfigurieren, Deployment Descriptors verstehen…“

Elyndra (lacht): „Spring Boot IST Java EE – nur mit Auto-Configuration drumherum. Es versteckt die Komplexität, eliminiert sie aber nicht.“

Cassian (zwischendurch): „Genau. Spring Boot startet einen embedded Tomcat oder Jetty. Das ist auch ein Servlet Container – nur unsichtbar.“

Nova: „Okay… aber brauche ich wirklich einen ganzen Application Server wie Payara? Tomcat reicht doch?“

Elyndra: „Kommt drauf an. Für ein einfaches REST API? Tomcat reicht. Für Enterprise mit Transactions, Message Queues, EJBs, Security Context Propagation über mehrere Services? Dann brauchst du den vollen Java EE Stack.“

Nova: „Und Spring Boot kann das nicht?“

Cassian: „Doch, kann es. Aber Spring Boot baut auf Java EE Konzepten auf. Wenn du die Basics nicht verstehst, kannst du nicht debuggen, wenn’s schief geht.“

Nova (seufzt): „Also muss ich erstmal die ‚alte Schule‘ lernen, bevor ich zur ’neuen Schule‘ gehe?“

Elyndra: „Exakt. Kennst du das Fundament, verstehst du Spring Boot in 2 Tagen. Überspringst du’s, stolperst du bei jedem Production-Issue.“

Nova: „Okay, macht Sinn. Lowkey bin ich froh, dass wir das von Grund auf machen.“

Cassian: „Real talk: Die meisten Devs überspringen diese Grundlagen. Dann kommen sie zu uns und fragen, warum ihre App im Production unter Last crasht. Weil sie nicht verstehen, was der Container macht.“

Nova (grinst): „Noted. Ich lerne erstmal, was unter der Haube passiert.“

Elyndra: „Das ist der Spirit! ☕“


✅ Checkpoint: Hast du es verstanden?

Bevor du weitermachst, teste dich selbst:

Quiz:

Frage 1: Was ist der Unterschied zwischen Java SE und Java EE?

Frage 2: Was macht ein Application Server?

Frage 3: Was ist der Webcontainer und was macht er?

Frage 4: Warum ist HTTP zustandslos und wie lösen wir das?

Frage 5: Was ist der Unterschied zwischen GET und POST?

Mini-Challenge:

Aufgabe: Erstelle ein Servlet, das „Hello, [Name]!“ ausgibt.

Die URL soll sein: http://localhost:8080/HelloPayara/greet?name=Anna

Hinweise:

  1. Erstelle eine neue Klasse im src/main/java Ordner
  2. Die Klasse muss HttpServlet erweitern
  3. Verwende @WebServlet Annotation für URL-Mapping
  4. Implementiere doGet()
  5. Lies den Parameter name aus dem Request
  6. Schreibe die Response mit response.getWriter()

Lösung:
Die Lösung zu dieser Challenge findest du am Anfang von Tag 2 als Kurzwiederholung! 🚀

Alternativ kannst du die Musterlösung im GitHub-Projekt checken: [Link folgt]


Geschafft? 🎉
Dann bist du bereit für die FAQ-Sektion!

Nicht sicher?
Kein Problem! Geh nochmal zurück zu den Servlet-Lifecycle-Abschnitten und experimentiere mit dem Code.


❓ Häufig gestellte Fragen

Frage 1: Warum nicht einfach Spring Boot nutzen statt Java EE?

Spring Boot ist großartig, aber es IST Java EE (bzw. Jakarta EE) unter der Haube. Wenn du die Grundlagen nicht verstehst, kannst du Spring Boot nicht debuggen oder optimieren. Spring Boot versteckt die Komplexität – aber in Production musst du wissen, WAS es versteckt.

Frage 2: Muss ich wirklich Payara verwenden? Was ist mit Tomcat?

Tomcat ist nur ein Servlet-Container (Webcontainer), kein vollständiger Application Server. Er unterstützt nur Servlets und JSPs, aber keine EJBs, JTA, JMS, etc.

Für diesen Kurs nutzen wir Payara, weil es den vollen Jakarta EE Stack bietet. Später kannst du zu Tomcat, WildFly, WebSphere oder einem anderen Server wechseln – die Konzepte bleiben gleich.

Frage 3: Ist Java EE tot?

Nein! Es heißt jetzt Jakarta EE (seit 2019) und wird aktiv von der Eclipse Foundation weiterentwickelt. Spring Boot, Quarkus, Micronaut – alle nutzen Jakarta EE Specs unter der Haube. Die Konzepte bleiben hochrelevant.

Frage 4: Wie lange dauert es, bis ich produktionsreif bin?

Nach diesem 10-Tage-Kurs hast du die theoretischen Grundlagen. Production-Ready wirst du nach ~3-6 Monaten Praxis mit echten Projekten, Code-Reviews und dem Erleben von Production-Issues. Lernen ist ein Marathon, kein Sprint.

Frage 5: Kann ich Java EE mit Docker nutzen?

Absolut! Application Server laufen perfekt in Containern. Du packst Payara + deine WAR-Datei in ein Docker Image und deployest es. Wir kommen in späteren Kursen zu Docker + Kubernetes mit Java EE.

Frage 6: Was ist besser – Java EE oder Node.js?

Das ist wie „Hammer vs. Schraubenzieher“ – kommt auf den Job an.

Java EE ist stark bei:

  • Enterprise-Apps mit Transaktionen
  • Security & Compliance
  • Langlebige, wartbare Systeme
  • Große Teams mit klarer Struktur

Node.js ist stark bei:

  • Rapid Prototyping
  • Real-time Apps (Websockets, Streams)
  • Kleine Teams, schnelle Iterations
  • I/O-intensive Apps

Beide haben ihre Berechtigung.

Frage 7: Bernd meinte mal, Java EE wäre „overcomplicated for most things“. Hat er recht?

Lowkey ja. Für ein kleines Blog-System mit 50 Usern brauchst du keinen Application Server mit EJBs, JTA und JMS. Da reicht Spring Boot mit embedded Tomcat oder sogar eine statische Site.

Aber für ein Banking-System mit:

  • 10.000 gleichzeitigen Usern
  • Verteilten Transaktionen über mehrere Datenbanken
  • Message Queues für asynchrone Verarbeitung
  • Security Context Propagation
  • Audit Logging
  • Clustering und Failover

…dann ist der volle Jakarta EE Stack genau richtig.

Real talk: Es kommt auf den Use-Case an. Bernd hat recht – für „most things“ ist es overkill. Aber für Enterprise ist es unverzichtbar.


📚 Quiz-Lösungen

Hier sind die Antworten zum Quiz von oben:


Frage 1: Was ist der Unterschied zwischen Java SE und Java EE?

Antwort:

Java SE ist die Standard Edition für Desktop- und Konsolen-Anwendungen.

Java EE (Enterprise Edition) baut auf Java SE auf und fügt APIs für Enterprise-Anwendungen hinzu:

  • Servlets
  • JSP
  • EJB
  • JPA
  • CDI
  • JAX-RS
  • JMS
  • JTA
  • Etc.

Java EE ist ein Standard (Spezifikation), kein Framework. Application Server implementieren diesen Standard.


Frage 2: Was macht ein Application Server?

Antwort:

Ein Application Server:

  1. Implementiert den Java EE / Jakarta EE Standard
  2. Stellt eine Laufzeitumgebung für Java EE Komponenten bereit
  3. Verwaltet den Lifecycle deiner Komponenten (Servlets, EJBs, etc.)
  4. Bietet Services:
    • HTTP Request Handling (via Webcontainer)
    • Connection Pooling
    • Threading / Concurrency Management
    • Security & Authentication
    • Transaction Management
    • Dependency Injection
  5. Du konzentrierst dich auf Business-Logik, der Server kümmert sich um Infrastruktur!

Frage 3: Was ist der Webcontainer und was macht er?

Antwort:

Der Webcontainer (Servlet Container) ist eine Komponente des Application Servers, die speziell für Web-Anwendungen zuständig ist.

Er:

  1. Verarbeitet HTTP-Requests und -Responses
  2. Verwaltet Servlets und JSPs (Lifecycle: init, service, destroy)
  3. Erstellt HttpServletRequest und HttpServletResponse Objekte
  4. Ruft die passenden Servlets auf (via URL-Mapping)
  5. Managed Sessions (via Cookies und Session-IDs)
  6. Kümmert sich um Thread-Management pro Request

Du schreibst NICHT den Code für HTTP-Handling – der Webcontainer macht das für dich!


Frage 4: Warum ist HTTP zustandslos und wie lösen wir das?

Antwort:

Zustandslos bedeutet:

Der Server „erinnert sich nicht“ an vorherige Requests. Jeder Request ist komplett unabhängig.

Problem:

Wir brauchen aber Zustand! Beispiele:

  • User-Login (wer ist eingeloggt?)
  • Warenkorb (was liegt drin?)
  • Multi-Step-Formulare (wo bin ich im Prozess?)

Lösung: Sessions

  1. Server erstellt eine eindeutige Session-ID (z.B. JSESSIONID=ABC123)
  2. Schickt die ID als Cookie an den Browser
  3. Browser sendet den Cookie bei jedem weiteren Request automatisch mit
  4. Server erkennt anhand der Session-ID den User und lädt den gespeicherten Zustand

In Java:

HttpSession session = request.getSession();
session.setAttribute("user", email);

Der Webcontainer verwaltet Sessions automatisch via Cookies!


Frage 5: Was ist der Unterschied zwischen GET und POST?

Antwort:

GET:

  • Daten abrufen (Read-Operation)
  • Parameter in URL sichtbar: /products?id=123&category=electronics
  • Kein Request Body
  • Kann gecached werden
  • Kann als Bookmark gespeichert werden
  • Nicht für sensible Daten (Passwörter sichtbar in URL!)
  • Idempotent (mehrfaches Ausführen = gleiches Ergebnis)

POST:

  • Daten senden / erstellen (Create/Update)
  • Parameter im Request Body (nicht in URL sichtbar)
  • Kann große Datenmengen übertragen
  • Wird nicht gecached
  • Für sensible Daten (Passwörter, Kreditkarten)
  • Nicht idempotent (mehrfaches Ausführen kann unterschiedliche Ergebnisse haben)

Regel:

  • Login-Formulare → POST
  • Suchanfragen → GET
  • Daten nur abrufen → GET
  • Daten erstellen/ändern → POST (oder PUT/PATCH/DELETE)

🎉 Tag 1 geschafft!

Du rockst! 🚀

Real talk: Das war ein intensiver Tag. Viel Theorie, viele neue Konzepte. Wenn dir der Kopf raucht – völlig normal!

Das hast du heute gelernt:

  • ✅ Was Java EE ist und wie es sich von Java SE unterscheidet
  • ✅ Was ein Application Server ist und welche Aufgaben er hat
  • ✅ Was der Webcontainer macht (Request-Handling, Servlet-Lifecycle)
  • ✅ Wie das Client-Server-Modell funktioniert
  • ✅ Wie HTTP-Requests und -Responses aufgebaut sind
  • ✅ Was Zustandslosigkeit bedeutet und wie Sessions funktionieren
  • ✅ Wie man Payara Server in NetBeans einrichtet
  • ✅ Wie man ein erstes Java EE Projekt erstellt und deployed

Du kannst jetzt:

  • Die Architektur einer Java Webanwendung erklären
  • Den Unterschied zwischen Application Server und Webcontainer beschreiben
  • HTTP-Requests und -Responses verstehen
  • Ein einfaches Servlet schreiben und deployen

Honestly? Das ist HUGE! Viele Developer stolpern über diese Konzepte, weil sie zu schnell zu Spring Boot springen, ohne die Grundlagen zu verstehen.

Du hast jetzt das Fundament. Und das ist Gold wert.


Wie geht’s weiter?

Morgen (Tag 2): HTTP-Protokoll Vertiefung & Zustandslosigkeit
Was dich erwartet:

  • HTTP-Methoden im Detail (GET, POST, PUT, DELETE, PATCH)
  • Status-Codes verstehen (nicht nur 200 und 404!)
  • HTTP-Headers und ihre Bedeutung
  • Content-Negotiation
  • HTTPS und Security
  • Sessions und Cookies im Detail – das wird dein Game-Changer für User-Auth! 🔥

Brauchst du eine Pause?
Mach sie! Lernen braucht Zeit. Dieser Content setzt sich erst richtig, wenn du ihn verdaut hast.

Tipp für heute
Spiel mit dem HelloPayara-Projekt! Ändere den Code, probiere verschiedene URLs, schau dir die HTTP-Requests im Browser-DevTools an (F12 → Network-Tab).

Learning by doing! 🔧


Troubleshooting

Problem: Payara Server startet nicht in NetBeans

Lösung:

  1. Prüfe, ob JDK 21 installiert ist (nicht nur JRE!)
  2. Prüfe, ob Port 8080 frei ist:netstat -an | findstr 8080
  3. Schau ins NetBeans Output-Fenster für Fehlermeldungen
  4. Versuche Payara manuell zu starten:C:\payara6\bin\asadmin start-domain

Problem: „The module has not been deployed“

Lösung:

  1. Clean and Build: Rechtsklick auf Projekt → Clean and Build
  2. Undeploy manually: Services → Payara Server → Applications → Rechtsklick → Undeploy
  3. Nochmal Run

Problem: 404 Not Found

Lösung:

  1. Prüfe die URL – ist der Context-Path richtig?
  2. Prüfe ob die App deployed ist: Admin-Console → Applications
  3. Prüfe das URL-Mapping im Servlet: @WebServlet("/greet")

Problem: ClassNotFoundException

Lösung:

  1. Prüfe die pom.xml – sind alle Dependencies vorhanden?
  2. Maven Reimport: Rechtsklick auf Projekt → Reload POM
  3. Clean and Build

Feedback?

War dieser Tag zu schnell? Zu langsam? Zu schwer? Zu viel Theorie?

Schreib uns: feedback@java-developer.online

Wir wollen, dass du erfolgreich lernst! Dein Feedback hilft uns, den Kurs besser zu machen.


Offizielle Dokumentation:

HTTP:

Weiterführend:


Bis morgen! 👋

Elyndra

elyndra@java-developer.online
Senior Developer bei Java Fleet Systems Consulting


Java Web Basic – Tag 1 von 10
Teil der Java Fleet Learning-Serie
© 2025 Java Fleet Systems Consulting