CodeGym /Java Blog /Random-IT /Creazione di una semplice applicazione Web utilizzando se...
John Squirrels
Livello 41
San Francisco

Creazione di una semplice applicazione Web utilizzando servlet e JSP (parte 1)

Pubblicato nel gruppo Random-IT
Conoscenze richieste per comprendere l'articolo: hai già più o meno capito Java Core e vorresti esaminare le tecnologie JavaEE e la programmazione web . Sarebbe più sensato che tu stia attualmente studiando la ricerca Java Collections , che tratta argomenti vicini all'articolo.
Creazione di una semplice applicazione Web utilizzando servlet e JSP (parte 1) - 1
Questo materiale è la logica continuazione del mio articolo Creare il progetto web più semplice in IntelliJ Idea Enterprise . In quell'articolo, ho dimostrato come creare un modello di progetto web funzionante. Questa volta ti mostrerò come creare un'applicazione web semplice ma totalmente attraente utilizzando l' API Java Servlet e l' API JavaServer Pages . La nostra applicazione avrà una home page con due link:
  • un collegamento a una pagina per l'aggiunta di utenti;
  • un collegamento all'elenco degli utenti.
Come prima, userò IntelliJ Idea Enterprise Edition , Apache Maven (collegheremo solo alcune dipendenze) e Apache Tomcat . Alla fine, "abbelliremo" la nostra applicazione utilizzando il framework W3.CSS . Supponiamo che tu abbia già un progetto vuoto a cui ora aggiungeremo. In caso contrario, leggi il primo articolo e creane uno. Ci vorranno solo pochi minuti :)

Un po' sulla struttura della nostra futura applicazione

La nostra home page (/) sarà una normale pagina HTML statica con un'intestazione e due collegamenti/pulsanti:
  • aggiungi un nuovo utente (naviga su / add );
  • visualizzare l'elenco degli utenti (naviga su / list ).
Tomcat catturerà le richieste per questi indirizzi e le invierà a uno dei due servlet che andremo a creare (specificheremo la mappatura in web.xml ). I servlet elaboreranno quindi le richieste, prepareranno i dati (o salveranno i dati, se stiamo aggiungendo un utente) e trasferiranno il controllo ai file JSP appropriati , che poi "rendering" il risultato. Memorizzeremo i dati in un semplice elenco vanilla (Elenco).

Crea una home page statica

Se index.jsp nella tua cartella web, eliminalo. Invece, crea un semplice file HTML chiamato index.html in questa cartella:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My super project!</title>
</head>
<body>
    <!-- header -->
    <div>
        <h1>Super app!<//h1>
    </div>

    <div>       <!-- content -->
        <div>    <!-- button holder -->
            <button onclick="location.href='/list'">List users<//button>
            <button onclick="location.href='/add'">Add user<//button>
        </div>
    </div>
</body>
</html>
Non c'è niente di complicato qui. Nel tag title , indichiamo il titolo della nostra pagina. Nel corpo della pagina, abbiamo due div principali: header e content . Il contenuto div include un supporto per i nostri pulsanti. E lì abbiamo due pulsanti che ti portano all'indirizzo corrispondente con un clic. Puoi eseguire il progetto e vedere come appare ora. Se fai clic sui pulsanti, ottieni pagine di errore 404, perché le pagine corrispondenti non esistono ancora. Ma possiamo dire che i pulsanti funzionano. Si noti che questo non è l'approccio più universale: se JavaScript è disattivato nel browser, questi pulsanti non funzioneranno. Ma supponiamo che nessuno disabiliti JavaScript. :) Ovviamente, potresti cavartela con semplici link, ma io preferisco i bottoni. Puoi farlo come preferisci. E non preoccuparti del fatto che i miei esempi avranno molti div . Li riempiremo di stili più tardi e tutto sembrerà più bello. :)

Crea file JSP per eseguire il rendering del risultato

Nella stessa directory web , crea una cartella in cui aggiungeremo i nostri file JSP . L'ho chiamato ' viste ', ma ancora una volta si può improvvisare. In questa cartella, creeremo due file JSP:
  • add.jsp — una pagina per aggiungere utenti;
  • list.jsp — pagina per visualizzare l'elenco degli utenti.
Assegna loro intestazioni di pagina appropriate. Qualcosa come " Aggiungi nuovo utente " e " Elenco utenti ", e lo lasceremo così.

Crea due servlet

I servlet riceveranno ed elaboreranno le richieste che Tomcat invia loro. Nella cartella src/main/java , crea il pacchetto dell'app , dove inseriremo il nostro codice sorgente. Ci andranno anche altri pacchetti. Quindi, per evitare che questi pacchetti vengano creati uno dentro l'altro, creeremo una classe nel pacchetto dell'app (la elimineremo in seguito). Ora crea tre diversi pacchetti nel pacchetto dell'app :
  • entità — le nostre entità (la classe che descrive gli oggetti utente) vanno qui;
  • modello — qui è dove va il nostro modello (ne parleremo un po' più tardi);
  • servlet - ed è qui che vanno i nostri servlet.
Una volta fatto ciò, puoi tranquillamente eliminare quella classe dal pacchetto dell'app (se l'hai creata, ovviamente). Nel pacchetto servlet , crea due classi:
  • AddServlet — elabora le richieste inviate a / add ;
  • ListServlet — elabora le richieste inviate a / list .

Collegamento delle dipendenze in Maven

Tomcat 9 .* implementa le specifiche per Servlet 4.0 e JavaServer Pages 2.3 . Questo è quanto affermato nella seconda riga del primo paragrafo della documentazione ufficiale di Tomcat 9. Ciò significa che se tu, come me, utilizzi questa versione di Tomcat , il codice che scriverai ed eseguirai utilizzerà queste versioni. Ma vorremmo avere queste specifiche nel nostro progetto, in modo che il nostro codice, che le utilizza, almeno si compili correttamente. E per fare questo, dobbiamo caricarli nel nostro progetto. È qui che Maven viene in soccorso.

La regola generale è questa: se devi collegare qualcosa al tuo progetto usando Maven:

  • vai al sito Web del repository da Maven;
  • trova la versione richiesta della libreria richiesta;
  • ottieni il codice di dipendenza che deve essere incollato nel tuo pom.xml;
  • impasto! :)
Cominciamo. Innanzitutto, prepara il file POM . Da qualche parte dopo la voce /version , ma prima di /project , inserisci quanto segue:

<dependencies>

</dependencies>
Lo facciamo per indicare che elencheremo le dipendenze richieste all'interno di questi tag. Ora vai su mvnrepository.com . C'è un campo di ricerca in alto. Per iniziare, cerca " servlet ". Il primo risultato, che è stato utilizzato più di settemila volte, ci sta bene. Ricorda, abbiamo bisogno della versione 4.0 (per Tomcat 9). Altre versioni potrebbero essere appropriate per implementazioni precedenti. Questa è una versione abbastanza recente, quindi non ci sono molti usi. Ma ne abbiamo bisogno. Si apre una pagina in cui puoi ottenere il codice per questa dipendenza per una varietà di gestori di pacchetti, oppure puoi semplicemente scaricarlo. Ma dal momento che vogliamo connetterlo usando Maven, selezioneremo il codice nella scheda Maven. Copiamo e incolliamo nella sezione delle dipendenze del nostro file POM. Se ricevi una notifica che ti chiede se desideri abilitare l'importazione automatica nell'angolo in basso a destra di IDEA , procedi e accetta. Se hai rifiutato accidentalmente, vai su " Impostazioni " e attiva manualmente l'importazione automatica: Impostazioni (Ctrl + Alt + S) -> Build, Execution, Deployment -> Maven -> Importing .e i file di configurazione IDEA per questo progetto sincronizzati. Seguendo lo stesso principio, troveremo e connetteremo JavaServer Pages 2.3 (cercare "JSP"). E poiché abbiamo già avviato Maven, diciamo solo che i nostri file sorgente seguono la sintassi Java 8 e che dobbiamo compilarli in bytecode per quella versione. Dopo tutti questi passaggi, il nostro pom.xml sarà simile a questo:

<?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>cc.codegym.info.fatfaggy</groupId>
    <artifactId>my-super-project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compile.source>1.8</maven.compile.source>
        <maven.compile.target>1.8</maven.compile.target>
    </properties>

    <dependencies>
        <!-- Servlet API 4.0 for tomcat 9 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- JavaServer Pages API 2.3 for tomcat 9 -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>

Trasforma i nostri servlet in veri e propri servlet

Al momento, la coppia di servlet che abbiamo creato sono in realtà classi ordinarie. Non hanno alcuna funzionalità. Ma ora abbiamo collegato l' API Servlet al nostro progetto, e di conseguenza possiamo usare le sue classi. Per rendere i nostri servlet "reali", tutto ciò che dobbiamo fare è far loro ereditare la classe HttpServlet .

Mappatura o markup

Ora sarebbe carino dire in qualche modo a Tomcat che le richieste per l'indirizzo / add sono processate dal nostro AddServlet , e le richieste per l'indirizzo / list sono gestite dal ListServlet . Questo processo è chiamato mappatura (markup). Questo viene fatto in web.xml usando lo stesso principio:
  • per iniziare, descrivi il servlet (fornisci un nome e specifica il percorso della classe stessa);
  • quindi associare questo servlet a un indirizzo specifico (specificare il nome del servlet, che gli abbiamo appena assegnato, e specificare l'indirizzo le cui richieste devono essere inviate a questo servlet).
Descrivi il servlet:

<servlet>
    <servlet-name>add</servlet-name>
    <servlet-class>app.servlets.AddServlet</servlet-class>
</servlet>
Ora collegalo all'indirizzo:

<servlet-mapping>
    <servlet-name>add</servlet-name>
    <url-pattern>/add</url-pattern>
</servlet-mapping>
Come puoi vedere, servlet-name è lo stesso in entrambi i casi. Di conseguenza, Tomcat sa che se viene ricevuta una richiesta per /add, deve essere inviata a app.servlets.AddServlet. Facciamo la stessa cosa con il secondo servlet. Alla fine, il nostro web.xml ha approssimativamente il seguente contenuto:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- add servlet -->
    <servlet>
        <servlet-name>add</servlet-name>
        <servlet-class>app.servlets.AddServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>add</servlet-name>
        <url-pattern>/add</url-pattern>
    </servlet-mapping>

    <!-- list servlet -->
    <servlet>
        <servlet-name>list</servlet-name>
        <servlet-class>app.servlets.ListServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>list</servlet-name>
        <url-pattern>/list</url-pattern>
    </servlet-mapping>
</web-app>
A proposito, non abbiamo creato il markup per la home page (/). Il fatto è che in questo caso non ne abbiamo bisogno. La nostra home page è un semplice file HTML che mostra solo due pulsanti. Non ha contenuto dinamico, quindi non abbiamo bisogno di creare un servlet separato per le richieste da / che non farà altro che inoltrare l'esecuzione a qualche JSP (che dovrebbe anche essere creato) per disegnare due pulsanti per noi. Non abbiamo bisogno di questo. Una pagina statica ci si addice. Quando Tomcat riceve una richiesta, verificherà se esiste un singolo servlet in grado di elaborare la richiesta per quell'indirizzo, quindi vedrà che questo indirizzo in realtà contiene già il file HTML pronto, che servirà. Possiamo eseguire di nuovo la nostra applicazione (riavviare il server o ridistribuirlo di nuovo, qualunque cosa tu preferisca) e assicurarci che la home page sia visualizzata, che non si rompa nulla e che le transizioni si verifichino quando facciamo clic sui pulsanti (anche se riceviamo di nuovo un errore). A proposito, mentre prima ricevevamo un errore 404, ora otteniamo un 405. Significa che la mappatura ha funzionato e le servlet sono state trovate, ma non avevano un metodo adatto per gestire la richiesta.

Breve digressione: cosa succede "sotto il cofano"?

Probabilmente hai già pensato a come funziona la nostra applicazione in Tomcat. Cosa succede lì dentro? E dov'è il metodo main()? Non appena vai su localhost:8080 nel tuo browser, il browser invia una richiesta a questo indirizzo utilizzando il protocollo HTTP. Spero che tu sappia già che esistono molti tipi diversi di richieste e le più popolari sono GET e POST. Ogni richiesta dovrebbe essere esaudita. Una richiesta GET dovrebbe ricevere una risposta di codice HTML pronto per l'uso, restituito al browser. Il browser quindi sostituisce il codice con tutte le belle lettere, pulsanti e moduli. Una richiesta POST è un po' più interessante, poiché contiene anche alcune informazioni. Ad esempio, supponi di inserire le credenziali in un modulo di registrazione o di accesso su un sito Web e di fare clic su "Invia". Ciò fa sì che una richiesta POST con le tue informazioni personali venga inviata al server. Il server riceve queste informazioni, le elabora e restituisce una risposta (ad esempio, una pagina HTML con il tuo profilo). La principale differenza tra loro è che le richieste GET vengono utilizzate solo per recuperare dati dal server, mentre le richieste POST contengono alcune informazioni (e i dati sul server possono cambiare). Ad esempio, quando carichi la tua immagine sul server, viene trasferita lì in una richiesta POST e il server la aggiunge al database, cioè si verifica una modifica. Ora torniamo a Tomcat. Quando riceve una richiesta da un cliente, controlla l'indirizzo. Controlla se esiste un servlet adatto per elaborare le richieste per quell'indirizzo (o una risorsa disponibile che può essere restituita immediatamente). Se non trova qualcosa da restituire, quindi risponde con un errore 404 anziché una pagina HTML. Ma se trova un servlet adatto "seduto" a quell'indirizzo, esamina il tipo di richiesta (GET, POST o qualcos'altro) e chiede al servlet se ha un metodo in grado di gestire questo tipo di query. Se il servlet dice che non sa come gestire questo tipo, alloraTomcat restituisce un codice 405. Ed è proprio quello che è successo nel nostro progetto. Ma se viene trovato un servlet adatto e ha un metodo adatto, Tomcat crea un oggetto servlet, lo avvia su un nuovo thread(che lo lascia funzionare da solo) e Tomcat continua il proprio lavoro, accettando e inviando richieste. Inoltre, Tomcat crea altri due oggetti: un HttpServletRequest (che chiamerò "richiesta" in breve) e un HttpServletResponse (che chiamerò "risposta"). Mette tutti i dati ricevuti dalla richiesta del client nel primo oggetto, in modo che tutti i dati possano essere estratti da esso. E poi, dopo tutto questo, passa questi due oggetti al metodo appropriato del servlet che è stato avviato su un thread separato. Non appena il servlet termina il suo lavoro e ha una risposta pronta per essere inviata al client, sventola un flag a Tomcat, dicendo "Ho finito. Tutto è pronto". Tomcat riceve la risposta e la invia al client. Ciò consente a Tomcat di ricevere richieste e inviare risposte, senza distrarsi e tutto il lavoro viene svolto da servlet in esecuzione su thread separati. Ciò significa che quando scriviamo il codice servlet determiniamo quale lavoro verrà eseguito. E puoi pensare al metodo main() come situato all'interno di Tomcat stesso (sì, è scritto in Java), e quando "lanciamo" Tomcat, viene avviato il metodo main(). Creazione di una semplice applicazione web utilizzando servlet e JSP (parte 1) - 2

Usa i servlet per catturare i metodi GET e inviare risposte super semplici

Al momento, i nostri servlet non hanno metodi adatti (GET), quindi Tomcat restituisce un errore 405. Creiamoli! La classe HttpServlet, ereditiamo i nostri servlet, dichiara vari metodi. Per assegnare un codice specifico ai metodi, li sovrascriviamo semplicemente. In questo caso, dobbiamo sovrascrivere il doGet()metodo in entrambi i servlet.

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

}
Come puoi vedere, questo metodo accetta due argomenti: req (richiesta) e resp (risposta). Questi sono gli stessi oggetti che Tomcat crea e popola per noi quando chiama il metodo appropriato nel servlet. Per iniziare, creeremo le risposte più semplici. Per fare ciò, prenderemo l'oggetto resp e da esso otterremo un oggetto PrintWriter. Questo tipo di oggetto viene utilizzato per comporre una risposta. Lo useremo per produrre una stringa semplice.

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    PrintWriter writer = resp.getWriter();
    writer.println("GET method from AddServlet");
}
Faremo qualcosa di simile nel ListServlet, quindi riavvieremo il nostro server. Come puoi vedere, funziona tutto! Quando fai clic sui pulsanti, ottieni pagine con il testo che abbiamo "scritto" con PrintWriter. Ma i file JSP che abbiamo preparato per generare pagine con risposte non vengono utilizzati. Questo semplicemente perché non vengono mai giustiziati. Il nostro servlet crea la risposta stessa e termina l'esecuzione, segnalando a Tomcat che è pronto a rispondere al client. Tomcat prende semplicemente la risposta e la invia al client. Passiamo il controllo dai servlet ai file JSP. Modificheremo il codice dei nostri metodi come segue:
  • otteniamo un oggetto request dispatcher dall'oggetto request e gli passiamo l'indirizzo della pagina JSP a cui vogliamo trasferire il controllo;
  • usiamo questo oggetto per trasferire il controllo alla pagina JSP specificata, senza dimenticare di passare gli oggetti richiesta e risposta che abbiamo ricevuto da Tomcat.

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp");
    requestDispatcher.forward(req, resp);
}
Nel tag body delle pagine JSP, puoi aggiungere qualcosa in modo che possiamo vedere chiaramente quale pagina viene visualizzata. Dopo averlo fatto, riavvia il server e controlla. Facciamo clic sui pulsanti nella pagina principale e le pagine si aprono, il che significa che le richieste vengono inviate ai servlet. Quindi il controllo viene passato alle pagine JSP, che ora vengono visualizzate. È tutto per ora. Nella parte successiva di questo articolo, lavoreremo sulle funzionalità della nostra applicazione.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION