JavaRush /Java Blog /Random-IT /Creare una semplice applicazione web utilizzando servlet ...
fatfaggy
Livello 26
Киев

Creare una semplice applicazione web utilizzando servlet e jsp (parte 2)

Pubblicato nel gruppo Random-IT
Continuo a descrivere il processo di creazione di un'applicazione web utilizzando servlet, jsp, Maven e Tomcat. Inizio dell'articolo , se necessario.
Creiamo entità.
Creiamo una classe User nel pacchetto entità, in cui creeremo due variabili stringa private nome e password. Creiamo costruttori (predefinito e uno che accetti entrambi i valori), getter/setter, sovrascriviamo il metodo toString() per ogni evenienza, così come i metodi equals() e hashCode(). public class User { private String name; private String password; public User() { } public User(String name, String password) { this.name = name; this.password = password; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", password='" + password + '\'' + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (name != null ? !name.equals(user.name) : user.name != null) return false; return password != null ? password.equals(user.password) : user.password == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + (password != null ? password.hashCode() : 0); return result; } } Ora possiamo iniziare a creare un elenco di utenti, dove aggiungeremo i nostri utenti e da dove li porteremo per la visualizzazione. Ma c'è un problema. Non creiamo i nostri oggetti servlet; Tomcat li crea per noi. Anche i metodi che sovrascriviamo in essi sono già definiti per noi e non possiamo aggiungere un parametro. Come possiamo quindi creare un elenco comune che sia visibile in entrambi i nostri servlet? Se creiamo semplicemente il nostro oggetto elenco in ogni servlet, risulterà che aggiungeremo utenti a un elenco, ma visualizzare un elenco di utenti utilizzando il servlet ListServlet sarà completamente diverso. Si scopre che abbiamo bisogno di un oggetto che sia comune a entrambi i servlet. In generale, abbiamo bisogno di un oggetto che sia comune a tutte le classi del nostro programma; l'unico oggetto per l'intero programma. Spero che tu abbia sentito qualcosa sui design pattern. E forse per alcuni questa è la prima vera necessità di utilizzare il template Singleton nel proprio programma. Puoi essere creativo e creare dei fantastici singleton, con doppi controlli e sincronizzazione (sì, abbiamo un'applicazione multi-thread, poiché Tomcat esegue servlet in thread diversi), ma userò l'opzione con l'inizializzazione anticipata, poiché in questo caso abbastanza adatto.
Creazione di un modello.
Quindi creeremo una classe (e implementeremo al suo interno il modello singleton) nel pacchetto model, e la chiameremo anche in modo piuttosto colorito Model. Creiamo un oggetto elenco di utenti privati ​​al suo interno e creiamo due metodi: uno in modo da poter aggiungere un utente e il secondo: lasciamo che restituisca semplicemente un elenco di stringhe (nomi utente). Poiché il nostro oggetto utente è costituito da un nome e una password, non vorremmo "rivelare" le password degli utenti, quindi restituiremo solo un elenco dei loro nomi. public class Model { private static Model instance = new Model(); private List model; public static Model getInstance() { return instance; } private Model() { model = new ArrayList<>(); } public void add(User user) { model.add(user); } public List list() { return model.stream() .map(User::getName) .collect(Collectors.toList()); } }
Un po' di mvc.
Dato che hai sentito parlare di singleton, significa che probabilmente hai sentito parlare di un altro modello di progettazione: MVC (model-view-controller, o in russo model-view-controller, o proprio come in inglese model-view-controller). La sua essenza è separare la logica aziendale dalla presentazione. Cioè, separa il codice che determina cosa fare dal codice che determina come visualizzare i file . La View (view o semplicemente views) è responsabile della forma in cui vengono presentati alcuni dati. Nel nostro caso, le visualizzazioni sono le nostre pagine JSP. Ecco perché li ho inseriti in una cartella chiamata views. Il modello sono i dati effettivi con cui funziona il programma. Nel nostro caso si tratta di utenti (elenco di utenti). Ebbene, i controller sono l'anello di congiunzione tra loro. Prendono i dati dal modello e li trasferiscono alle visualizzazioni oppure ricevono alcuni dati da Tomcat, li elaborano e li trasferiscono al modello. La logica aziendale (ovvero cosa fare ) dovrebbe essere descritta in essi e non nel modello o nella vista. Quindi ognuno fa la sua cosa:
  • il modello memorizza i dati
  • Le visualizzazioni disegnano una bella rappresentazione dei dati
  • i titolari trattano i dati
Ciò consente a tutti loro di essere abbastanza semplici e gestibili. E non un mostruoso dump di tutto il codice in una classe. MVC non è adatto solo alla programmazione web, ma è ancora molto diffuso (se non sempre) in questo ambito. Nel nostro caso, i servlet fungeranno da controller. Sì, questa è una descrizione molto superficiale e persino approssimativa di questo pattern, ma questo articolo non riguarda i design pattern, ma su come realizzare una semplice applicazione web :) Chi vuole saperne di più: Google sa tutto ! :) Torniamo alle nostre opinioni.
Crea un modulo per aggiungere un utente.
Aggiungiamo un modulo al file add.jsp, composto da due input di testo (uno normale, l'altro di tipo password) e un pulsante per l'invio dei dati al server. Qui il modulo ha un attributo metodo con il valore post. Ciò significa che i dati di questo modulo verranno inviati al server sotto forma di richiesta POST. L'attributo action non è specificato, il che significa che questa richiesta verrà inviata allo stesso indirizzo a cui siamo andati in questa pagina (/add). Pertanto, il nostro servlet, che è legato a questo indirizzo, dopo aver ricevuto una richiesta GET, restituisce questo jsp con il modulo per aggiungere utenti e, se riceve una richiesta POST, questo modulo ha inviato lì i suoi dati (che recupereremo da l'oggetto request nel metodo doPost(), elaborarlo e trasferirlo al modello per il salvataggio). Vale la pena notare che qui gli input hanno un parametro name (per un campo con un nome ha il valore name e per un campo con una password ha il valore pass). Questo è un punto piuttosto importante. Poiché per ottenere questi dati (nome e password che verranno inseriti) dalla richiesta (già all'interno della servlet), utilizzeremo esattamente questi nome e pass. Ma ne parleremo più avanti. Il pulsante per l'invio dei dati stesso viene nuovamente realizzato sotto forma di pulsante e non di input, come di solito è consuetudine. Non so quanto sia universale questa opzione, ma per me funziona in Chrome :)
Elaborazione di una richiesta POST con un servlet.
Torniamo al servlet AddServlet. Sappiamo già che affinché la nostra servlet sia in grado di "catturare" le richieste GET, abbiamo sovrascritto il metodo doGet() dalla classe HttpServlet. Per insegnare alla nostra servlet a catturare anche le richieste POST, sovrascriviamo anche il metodo doPost(). Riceve oggetti di richiesta e risposta simili da Tomcat, con cui lavoreremo. Per prima cosa, estraiamo dalla richiesta il nome e passiamo i parametri inviati dal modulo (se li hai nominati diversamente nel modulo, allora quelli saranno i nomi che scriverai). Quindi creeremo il nostro oggetto utente utilizzando i dati ricevuti. Quindi otterremo l'oggetto del modello e aggiungeremo l'utente creato al modello. @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = req.getParameter("name"); String password = req.getParameter("pass"); User user = new User(name, password); Model model = Model.getInstance(); model.add(user); }
Trasferimento dei dati alla vista.
Passiamo ora al servlet ListServlet. Abbiamo già implementato il metodo doGet(), che trasferisce semplicemente il controllo alla vista list.jsp. Se non lo hai ancora, fallo per analogia con lo stesso metodo del servlet AddServlet. Ora sarebbe carino ottenere un elenco di nomi utente dal modello e passarli alla vista, che li riceverà lì e li visualizzerà bene. Per fare ciò, utilizzeremo nuovamente l'oggetto richiesta che abbiamo ricevuto da Tomcat. Possiamo aggiungere un attributo a questo oggetto, dandogli un nome e, di fatto, l'oggetto stesso che vorremmo trasferire alla vista. A causa del fatto che quando trasferiamo il processo di esecuzione dal servlet alla vista, passiamo lì gli stessi oggetti di richiesta e risposta che il servlet stesso ha ricevuto, quindi aggiungendo il nostro elenco di nomi all'oggetto della richiesta, possiamo quindi da questa richiesta oggetto nella vista crea il nostro elenco di nomi utente e ottieni. Abbiamo finito con la classe ListServlet, quindi ecco il codice dell'intera classe. package app.servlets; import app.model.Model; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; public class ListServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Model model = Model.getInstance(); List names = model.list(); req.setAttribute("userNames", names); RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/list.jsp"); requestDispatcher.forward(req, resp); } }
Esecuzione del codice Java nei file JSP.
Passiamo ora al file list.jsp. Questo file verrà eseguito solo quando ListServlet passa qui il processo di esecuzione. Inoltre, in quella servlet abbiamo già preparato un elenco di nomi utente dal modello e lo abbiamo passato qui nell'oggetto della richiesta. Dato un elenco di nomi, possiamo eseguire un ciclo for e stampare ciascun nome. Come ho già detto, i file jsp possono eseguire codice Java (in linea di principio, questo è ciò che li differenzia dalle pagine html statiche). Per eseguire del codice, è sufficiente posizionare una costruzione nel punto desiderato, <% // java code %> all'interno di tale costruzione otteniamo accesso a diverse variabili: request - il nostro oggetto richiesta, che abbiamo passato dal servlet, dove era semplicemente chiamato req risposta - l'oggetto risposta, nel servlet si chiamava resp out - un oggetto del tipo JspWriter (ereditato dal solito Writer), con l'aiuto del quale possiamo “scrivere” qualcosa direttamente nella pagina html stessa. Out.println("Ciao mondo!") è molto simile a System.out.println("Ciao mondo!"), ma non confonderli! out.println() "scrive" sulla pagina html e System.out.println - sull'output del sistema. Se chiami il metodo System.out.println() all'interno della sezione con il codice jsp, vedrai i risultati nella console Tomcat e non nella pagina, come potresti desiderare :) Puoi cercare altri oggetti disponibili all'interno di jsp Qui . Utilizzando l'oggetto request possiamo ottenere l'elenco dei nomi che è stato passato dal servlet (abbiamo allegato l'attributo corrispondente a questo oggetto) e utilizzando l'oggetto out possiamo visualizzare questi nomi. Facciamolo per ora semplicemente sotto forma di un elenco html: Se vogliamo visualizzare l'elenco solo quando sono presenti utenti, e altrimenti visualizzare un avviso che non ci sono ancora utenti, possiamo riscrivere un po' questa sezione: Ora che abbiamo sapere come trasferire i dati dai servlet alle visualizzazioni: possiamo migliorare leggermente il nostro AddServlet in modo che venga visualizzata una notifica sull'aggiunta riuscita di un utente. Per fare ciò, nel metodo doPost(), dopo aver aggiunto un nuovo utente al modello, possiamo aggiungere il nome di questo utente agli attributi dell'oggetto req e restituire il controllo alla vista add.jsp. E crea già una sezione con codice Java in cui puoi verificare se tale attributo è presente nella richiesta e, in tal caso, visualizzare un messaggio che l'utente è stato aggiunto con successo. Dopo queste modifiche, il codice completo della servlet AddServlet sarà simile a questo: Qui, alla fine del metodo doPost(), impostiamo un attributo con il nome dell'utente aggiunto al modello, quindi chiamiamo il metodo doGet( ), al quale passiamo la richiesta e la risposta correnti. E il metodo doGet() trasferisce già il controllo alla vista, dove invia un oggetto di richiesta con il nome dell'utente aggiunto allegato come attributo. Resta da correggere lo stesso add.jsp in modo che visualizzi tale notifica se tale attributo è presente. Add.jsp finale
    <% List names = (List ) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { for (String s : names) { out.println("
  • " + s + "
  • "); } } %>
<% List names = (List ) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { out.println(" "); for (String s : names) { out.println("
  • " + s + "
  • "); } out.println("
    "); } else out.println("

    There are no users yet!

    "); %>
    package app.servlets; import app.entities.User; import app.model.Model; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class AddServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp"); requestDispatcher.forward(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = req.getParameter("name"); String password = req.getParameter("pass"); User user = new User(name, password); Model model = Model.getInstance(); model.add(user); req.setAttribute("userName", name); doGet(req, resp); } } <%@ page contentType="text/html;charset=UTF-8" language="java" %> Add new user

    Super app!

    <% if (request.getAttribute("userName") != null) { out.println("

    User '" + request.getAttribute("userName") + "' added!

    "); } %>

    Add user

    Il corpo della pagina è costituito da un div con un'intestazione, dopo di che c'è un div contenitore per il contenuto, in cui viene verificato se esiste un attributo con il nome utente, quindi un div con un modulo per aggiungere utenti e alla fine un piè di pagina con un pulsante per tornare alla pagina principale. Potrebbe sembrare che ci siano troppi div, ma li useremo più tardi quando aggiungeremo gli stili :) Bene, la versione finale è list.jsp. Quindi , abbiamo un'applicazione web completamente funzionante che può anche memorizzare e aggiungere utenti come visualizzare un elenco dei loro nomi. Non resta che abbellirlo... :) <%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> Users

    Super app!

    Users

    <% List names = (List ) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { out.println(" "); for (String s : names) { out.println("
  • " + s + "
  • "); } out.println("
    "); } else out.println("

    There are no users yet!

    "); %>
    Aggiunta di stili. Utilizziamo il framework W3.CSS.
    Al momento, la nostra applicazione funziona, ma è assolutamente pazzesca :) Dobbiamo aggiungere uno sfondo, colori per testo e pulsanti, stilizzare elenchi, allineare, aggiungere rientri, in generale molte cose. Se scrivi gli stili manualmente, può richiedere molto tempo e nervi. Pertanto, suggerisco di utilizzare il framework CSS W3.CSS . Dispone già di classi già pronte con stili; non resta che posizionare nei posti giusti le classi CSS che vogliamo applicare in questi posti. Per aggiungerli alle nostre pagine, dobbiamo prima includere un file con gli stili. Puoi farlo in due modi: 1. sfoglia le nostre pagine e nella sezione head inserisci un collegamento diretto al file con gli stili, questa opzione è adatta se hai una connessione Internet costante. Quindi, quando apri le tue pagine su un server locale, gli stili verranno estratti da Internet. 2. Se vuoi avere tutti gli stili localmente e non dipendere da una connessione Internet, puoi semplicemente scaricare il file con gli stili e posizionarlo da qualche parte all'interno della cartella web (ad esempio web/styles/w3.css), quindi scorri tutte le nostre pagine (index.html, add.jsp, list.jsp) e inserisci un link a questo file con gli stili all'interno della sezione head, dopodiché sfoglia i tag e taggali con gli stili che ti piacciono . Non mi soffermerò su questo in dettaglio, ma fornirò immediatamente le mie versioni già pronte dei miei tre file con classi di stile organizzate. index.html add.jsp list.jsp Questo è tutto :) Se hai ancora domande o commenti o, al contrario, qualcosa non funziona, lascia un commento. Bene, allegherò un paio di screenshot di ciò che è venuto fuori da tutto questo. E infine. Se vuoi esercitarti con questo progetto, puoi provare: Super app!

    Super app!

    <%@ page contentType="text/html;charset=UTF-8" language="java" %> Add new user

    Super app!

    <% if (request.getAttribute("userName") != null) { out.println("
    \n" + " ×\n" + "
    User '" + request.getAttribute("userName") + "' added!
    \n" + "
    "); } %>

    Add user

    <%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> Users list

    Super app!

    Users

    <% List names = (List ) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { out.println("
      "); for (String s : names) { out.println("
    • " + s + "
    • "); } out.println("
    "); } else out.println("
    \n" + " ×\n" + "
    There are no users yet!
    \n" + "
    "); %>
    Home page dell'applicazione Aggiungi finestra utente un elenco di utenti
    • crea un servlet e un jsp per eliminare un utente e un altro paio per cambiare/modificare un utente esistente. Otterrai una vera applicazione web CrUD :) su servlet))
    • sostituire l'elenco (List ) per lavorare con il database in modo che gli utenti aggiunti non scompaiano dopo il riavvio del server :)
    Buona fortuna!
    Commenti
    TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
    GO TO FULL VERSION