Le **Servlet** sono componenti lato server scritti in Java che estendono le funzionalità di un web server. Sono il cuore del framework Java EE (Enterprise Edition) per il web e gestiscono il modello **Request/Response**. ## Architettura 3-Tier Le applicazioni web moderne sono divise in tre livelli logici: 1. **Presentation Tier:** L'interfaccia utente (HTML, CSS, JS). 2. **Logic Tier:** Il cervello dell'app (Servlet, Application Server come Tomcat). Si occupa della decodifica richieste, logica di business e sicurezza. 3. **Persistence Tier:** Dove i dati vengono salvati (Database, RDBMS). ## Cosa sono le Servlet? In termini pratici, una Servlet è una classe Java che estende `HttpServlet`. Gira all'interno di un **Web Container** (es. Apache Tomcat), che si occupa di gestire la rete e il ciclo di vita della servlet. ### Esempio Base: HelloServlet ```java import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Legge parametri dalla URL: ?nome=Mario String nome = request.getParameter("nome"); if (nome == null) nome = "Mondo"; // Imposta il tipo di contenuto response.setContentType("text/html"); // Scrive la risposta PrintWriter out = response.getWriter(); out.println(""); out.println("

Ciao " + nome + "!

"); out.println(""); } } ``` ## Ciclo di Vita della Servlet Il container gestisce la servlet in tre fasi principali: 1. **`init()`**: Eseguito una sola volta quando la servlet viene caricata in memoria. Si usa per operazioni costose (es. aprire connessione DB). 2. **`service()`**: Chiamato ad ogni richiesta. Delega il lavoro a `doGet`, `doPost`, `doPut`, `doDelete` in base al metodo HTTP. 3. **`destroy()`**: Eseguito prima che la servlet venga rimossa dalla memoria (es. allo spegnimento del server). > [!WARNING] Multithreading > Di default, il container usa **un'unica istanza** della servlet per gestire molteplici richieste contemporaneamente in thread separati. Bisogna evitare l'uso di variabili d'istanza per memorizzare dati della richiesta, altrimenti si rischiano problemi di concorrenza. ## Gestione dello Stato HTTP è stateless. Per riconoscere l'utente tra più richieste, Java fornisce due strumenti: ### Cookie Dati salvati sul browser del client. ```java // Creazione Cookie c = new Cookie("user", "mario"); c.setMaxAge(3600); // 1 ora response.addCookie(c); // Lettura Cookie[] cookies = request.getCookies(); ``` ### Sessione (`HttpSession`) Dati salvati sul server, associati a un ID (JSESSIONID) solitamente scambiato via cookie. ```java // Ottieni o crea sessione HttpSession session = request.getSession(true); // Salva dato session.setAttribute("carrello", mioOggetto); // Recupera dato Carrello c = (Carrello) session.getAttribute("carrello"); // Termina sessione (Logout) session.invalidate(); ``` ## Navigazione: Include e Forward Le servlet possono delegare il lavoro ad altre risorse (altre servlet o JSP). * **`forward()`**: Il controllo passa completamente alla nuova risorsa. L'URL nel browser **non cambia**. ```java request.getRequestDispatcher("/success.jsp").forward(request, response); ``` * **`include()`**: Il contenuto di un'altra risorsa viene incluso nella risposta corrente. * **`sendRedirect()`**: Il server dice al browser di fare una nuova richiesta a un altro URL. L'URL nel browser **cambia**. ```java response.sendRedirect("login.html"); ``` ## Scoped Objects (Ambiti) In Java Web esistono 4 ambiti dove salvare attributi (coppie chiave-valore): 1. **Request Scope:** Valido solo per la singola richiesta (es. dati da passare a una JSP via forward). 2. **Session Scope:** Valido finché l'utente non chiude il browser o scade il timeout. 3. **Application Scope (`ServletContext`):** Globale per tutta l'applicazione (tutti gli utenti). 4. **Page Scope:** (Solo nelle JSP) Valido per la singola pagina.