Questo materiale fa parte della serie "Introduzione allo sviluppo aziendale". Articoli precedenti: Parte 5. Servlet e Java Servlet API.  Scrivere una semplice applicazione web - 1Sai già come scrivere applicazioni Java che visualizzano testo sulla console, ma non sai ancora come creare la tua prima applicazione web? Ottimo, mettiti comodo. In questo articolo faremo conoscenza con i servlet e scriveremo un'applicazione di cui vantarti con i tuoi amici senza inviare loro un file JAR e senza costringerli a scaricare Java. Scriviamo una semplice applicazione web . Se non hai già familiarità con gli approcci utilizzati nello sviluppo web, ti consiglio di iniziare leggendo il primo articolo della serie " Introduzione allo sviluppo aziendale ".

Che cos'è un servlet?

Innanzitutto, scopriamo cosa sono i servlet e perché ne senti parlare così spesso. L' API Java Servlet è un'API standardizzata destinata ad essere implementata sul server. Interagisce con i clienti secondo uno schema di richiesta-risposta. Un servlet è una classe che può ricevere richieste da un client e restituire risposte al client. In effetti, i servlet sono esattamente gli elementi costitutivi che utilizziamo per creare un'architettura client-server in Java. Ricorderete che abbiamo già parlato di quell'architettura in un altro degli articoli della serie. Non giriamo intorno al cespuglio: scriviamo subito un po' di codice.

Cosa serve per creare un'applicazione web

Per la massima praticità quando si lavora con i servlet Java, è necessario IntelliJ IDEA Ultimate Edition. È un prodotto a pagamento, ma puoi attivare una prova di 30 giorni o utilizzare la versione ad accesso anticipato, che è sempre gratuita. Inoltre, installa Apache Tomcat, il server della nostra applicazione. Tomcat è un servlet container: elabora le richieste in arrivo e le passa alla nostra applicazione. Scarica Tomcat qui .

Creiamo la nostra prima applicazione web

Se tutto è pronto, crea un progetto Maven. Se non hai familiarità con Maven, dai un'occhiata al precedente articolo . Cominciamo!
  1. In pom.xml, aggiungi una dipendenza javax.servlet-api e specifica il pacchetto WAR:

    
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
       <modelVersion>4.0.0</modelVersion>
    
       <groupId>org.example</groupId>
       <artifactId>servlets</artifactId>
       <version>1.0-SNAPSHOT</version>
       <packaging>war</packaging>
    
       <dependencies>
           <dependency>
               <groupId>javax.servlet</groupId>
               <artifactId>javax.servlet-api</artifactId>
               <version>4.0.1</version>
           </dependency>
       </dependencies>
    </project>
    

    Classe servlet semplice:

    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    @WebServlet("/hello")
    public class MainServlet extends HttpServlet {
    
       @Override
       protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           resp.setContentType("text/html");
           PrintWriter printWriter = resp.getWriter();
           printWriter.write("Hello!");
           printWriter.close();
       }
    }
    
  2. Per eseguire l'applicazione, è necessario creare una configurazione Tomcat:

    Parte 5. Servlet e Java Servlet API.  Scrivere una semplice applicazione web - 2Parte 5. Servlet e Java Servlet API.  Scrivere una semplice applicazione web - 3

  3. Successivamente, indichiamo quale versione di Tomcat utilizzeremo e l'URL e la porta per comunicare con il server. Dovresti avere qualcosa del genere:

    Parte 5. Servlet e Java Servlet API.  Scrivere una semplice applicazione web - 4
  4. Ora dobbiamo solo specificare l'artefatto (il progetto assemblato in un archivio JAR) che verrà distribuito nel contenitore. È possibile fare clic sul pulsante Correggi e selezionare guerra esplosa : ciò significa che dopo che il progetto è stato ricostruito, l'artefatto verrà automaticamente inserito nel contenitore servlet. Parte 5. Servlet e Java Servlet API.  Scrivere una semplice applicazione web - 5

  5. Il valore predefinito per il contesto dell'applicazione è servlets_war_exploded . Ciò significa che accediamo all'applicazione all'indirizzo: http://localhost:8080/servlets_war_exploded .

    Perché dovremmo volere del testo extra? Cancelliamo ciò che non è necessario. Ora l'indirizzo della nostra applicazione web è: http://localhost:8080 .

    Parte 5. Servlet e Java Servlet API.  Scrivere una semplice applicazione web - 6
  6. Fare clic su OK. Vediamo che ora possiamo lanciare l'applicazione:

    Parte 5. Servlet e Java Servlet API.  Scrivere una semplice applicazione web - 7

    Ora quando apri l'applicazione nel tuo browser, dovresti ricevere un errore 404. Questo ha senso, perché l'indirizzo http://localhost:8080/ necessita di un servlet mappato su "/", ma il nostro unico servlet mappato su "/hello" .

  7. Possiamo accedervi all'indirizzo http://localhost:8080/hello . Una volta fatto ciò, otteniamo la risposta attesa: la stringa "Ciao"!

Se tutto funziona, analizziamo il codice. Per creare un servlet HTTP da una classe ordinaria , deve ereditare la classe HttpServlet. Sopra la dichiarazione di classe, indichiamo l' @WebServlet()annotazione. Qui è dove leghiamo (o mappiamo) il servlet a un percorso specifico ("/hello"). Questa annotazione è apparsa solo in Java Servlet API 3.0, quindi Internet ha molti esempi in cui la mappatura del servlet avviene tramite un file XML. Questo non è più necessario. Per gestire le richieste GET , sovrascriviamo il doGet()metodo. Prestare attenzione ai parametri del metodo: HttpServletRequeste HttpServletResponse. L' HttpServletRequestoggetto ci fornisce tutte le informazioni necessarie sulla richiesta. In HttpServletResponse, scriviamo la nostra risposta e impostiamo le intestazioni necessarie.

Lavorare con i parametri e una sessione

Miglioriamo il nostro servlet in modo che possa elaborare i parametri della richiesta e lavorare con una sessione:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/hello")
public class MainServlet extends HttpServlet {

   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       HttpSession session = req.getSession();
       Integer visitCounter = (Integer) session.getAttribute("visitCounter");
       if (visitCounter == null) {
           visitCounter = 1;
       } else {
           visitCounter++;
       }
       session.setAttribute("visitCounter", visitCounter);
       String username = req.getParameter("username");
       resp.setContentType("text/html");
       PrintWriter printWriter = resp.getWriter();
       if (username == null) {
           printWriter.write("Hello, Anonymous" + "<br>");
       } else {
           printWriter.write("Hello, " + username + "<br>");
       }
       printWriter.write("Page was visited " + visitCounter + " times.");
       printWriter.close();
   }
}
Ora il servlet funziona con una sessione, aumentando il valore di visitCounterogni volta che la pagina viene visitata. Se l' visitCounterattributo non è stato ancora creato (alla prima visita alla pagina), il getAttribute()metodo restituisce null, quindi è necessario verificare la presenza di null. Lo stesso vale per i parametri di richiesta. Se l'utente non passa il parametro username, il suo valore sarà nullo. In questo caso, salutiamo l'utente come visitatore anonimo. Per passare un parametro in una richiesta GET, viene utilizzata una stringa di query, ad esempio, potremmo utilizzare il seguente URL: http:// localhost:8080/hello? Nome utente=Paolo. Puoi leggere ulteriori informazioni sulle richieste HTTP nell'articolo precedentenella serie. La nostra applicazione al momento non ha molta logica, ma è un po' fastidioso ricevere un errore 404 nel percorso root. Per risolvere questo problema, creeremo un altro servlet e lo mapperemo alla pagina iniziale: @WebServlet("/"). Lo scopo di questo servlet è reindirizzare le richieste al percorso "/hello". Ci sono due modi per farlo: usando "forward" o "redirect". Forse vale la pena capire la differenza tra loro. Un forward delega l'elaborazione della richiesta a un altro servlet sul server. Il cliente non è coinvolto. Per fare ciò, aggiungi il seguente codice al metodo doGet() del nuovo servlet:

getServletContext().getRequestDispatcher("/hello").forward(req, resp);
In questo codice, accediamo al contesto servlet, otteniamo il dispatcher della richiesta per il servlet pertinente e gli chiediamo di elaborare una richiesta specifica con gli argomenti specificati (req, resp). Un reindirizzamento restituisce al client l'indirizzo che il client deve utilizzare per elaborare la sua richiesta. La maggior parte dei browser passa automaticamente all'URL restituito. Per implementare un reindirizzamento, è necessario aggiungere questo codice:

resp.sendRedirect(req.getContextPath() + "/hello");
Chiamiamo il redirect()metodo sul HttpServletResponseparametro e gli passiamo l'indirizzo che il client deve utilizzare. Ecco un dettaglio importante: i parametri HTTP devono essere aggiunti anche alla fine del percorso di reindirizzamento completo, il che non è molto conveniente. Nella nostra situazione è preferibile usare forward, ma a volte usare redirectè meglio. Se comprendi la differenza nel modo in cui funzionano, non farai la scelta sbagliata. Il codice per il nuovo servlet è simile al seguente:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/")
public class IndexServlet extends HttpServlet {

   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        getServletContext().getRequestDispatcher("/hello").forward(req, resp);
       resp.sendRedirect(req.getContextPath() + "/hello");
   }
}

Riepilogo

La tua prima applicazione web è terminata. Nel prossimo articolo imparerai come distribuirlo senza utilizzare IntelliJ IDEA. Abbiamo scritto un'applicazione che elabora solo le richieste GET. I metodi HTTP rimanenti vengono gestiti in modo simile, sovrascrivendo i metodi corrispondenti della classe genitore. È possibile utilizzare semplici servlet come questo per creare sofisticate applicazioni Web versatili. Ovviamente, l'utilizzo di framework di grandi dimensioni come Spring lo rende molto più semplice. Ma se vuoi davvero approfondire tutte le funzionalità dei servlet, puoi leggere le specifiche ufficiali . Parte 6. Contenitori servlet Parte 7. Introduzione al pattern MVC (Model-View-Controller).