CodeGym /Blog Java /Aleatoriu /Crearea unei aplicații web simple folosind servlet-uri și...
John Squirrels
Nivel
San Francisco

Crearea unei aplicații web simple folosind servlet-uri și JSP-uri (partea 2)

Publicat în grup
Crearea unei aplicații web simplă utilizând servlet-uri și JSP-uri (partea 1) Cunoștințe necesare pentru a înțelege articolul: deja v-ați dat seama mai mult sau mai puțin de Java Core și ați dori să vă uitați la tehnologiile JavaEE și la programarea web. Ar fi cel mai logic să studiezi în prezent misiunea Java Collections, care tratează subiecte apropiate articolului.
Crearea unei aplicații web simple folosind servlet-uri și JSP-uri (partea 2) - 1

Crearea de entități

În pachetul de entități , vom crea o Userclasă care are două variabile șir private: nume și parolă . Creați constructori (implicit și unul care ia ambele valori) și getters/setters și suprascrieți toString()metoda pentru orice eventualitate, împreună cu metodele equals()și hashCode(). Cu alte cuvinte, vom face tot ce face un dezvoltator Java respectabil când creează o clasă.

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;
    }
}
Acum putem începe să creăm o listă de utilizatori. Vom adăuga utilizatori la acesta și vom lua utilizatori din el pentru a le afișa. Cu toate acestea, avem o problemă. Nu creăm obiectele noastre servlet. Tomcat face asta pentru noi. Metodele pe care le suprascriem în ele sunt deja definite pentru noi, iar parametrii nu le putem. Cum creăm o listă partajată care va fi vizibilă în ambele servlet-uri? Dacă creăm doar un obiect listă în fiecare servlet, atunci am adăuga utilizatori la o listă, dar am afișa utilizatori dintr-o alta în ListServlet. Deci avem nevoie de un obiect care este partajat de ambele servlet-uri. În general, avem nevoie de un obiect care este partajat de toate clasele din programul nostru: un obiect pentru întregul program. Sper că ați auzit ceva despre modelele de design. Pentru unii oameni, aceasta poate fi prima nevoie reală pentru modelul Singleton în programul lor. Ați putea să vă faceți pași și să scoateți niște Singleton dulce cu verificări duble și sincronizare (da, aplicația noastră este multithreaded, deoarece servlet-urile Tomcat rulează pe fire separate). Dar voi folosi tehnica de inițializare timpurie, pentru că este complet adecvată pentru scopurile noastre de aici.

Crearea unui model

Creați o clasă (și implementați modelul Singleton ) în pachetul modelului și numiți-o ceva neobișnuit. De exemplu, Model . Vom crea o listă privată de utilizatori din clasa noastră și vom implementa două metode: una pentru a adăuga un utilizator și alta pentru a returna o listă de șiruri de caractere (nume de utilizator). Deoarece obiectul nostru utilizator constă dintr-un nume de utilizator și o parolă și nu dorim să dezvăluim parolele de utilizator, vom avea doar o listă de nume.

public class Model {
    private static Model instance = new Model();

    private List<User> model;

    public static Model getInstance() {
        return instance;
    }

    private Model() {
        model = new ArrayList<>();
    }

    public void add(User user) {
        model.add(user);
    }

    public List<String> list() {
        return model.stream()
                .map(User::getName)
                .collect(Collectors.toList());
    }
}

Un pic despre MVC

Deoarece ați auzit deja despre singleton , probabil ați auzit despre un alt model de design model-view-controller (MVC). Scopul său este de a separa logica de afaceri de vedere. Adică, pentru a separa codul care determină ce trebuie făcut de codul care determină modul de afișare a lucrurilor. Vizualizarea este responsabilă pentru modul în care sunt prezentate datele. În cazul nostru, vizualizările sunt paginile noastre JSP . Tocmai de aceea le-am pus într-un folder numit views . Modelul este datele cu care programul funcționează de fapt. În cazul nostru, aceștia sunt utilizatorii (lista de utilizatori). Și controlorii sunt legătura dintre ei. Ei preiau date din model și le transmit vizualizărilor (sau primesc unele date de la Tomcat, procesați-l și transmiteți-l modelului). Îți definești logica de afaceri (ce ar trebui să facă programul) în ele, nu în model sau vedere. Astfel, fiecare parte se ocupă de propria afacere:
  • modelul stochează date;
  • vizualizările oferă reprezentări frumoase ale datelor;
  • operatorii se ocupă de prelucrarea datelor.
Acest lucru permite programului să fie destul de simplu și ușor de întreținut, mai degrabă decât o grămadă monstruoasă de tot codul dintr-o singură clasă. MVC nu este potrivit doar pentru programarea web, dar este folosit mai ales des în acest domeniu (aproape întotdeauna). În cazul nostru, servleturile vor acționa ca controlori. Aceasta este o descriere foarte superficială și scurtă a modelului, dar MVC nu este subiectul principal al acestui articol. Dacă cineva dorește să afle mai multe, Google este prietenul tău! Creați un formular pentru adăugarea unui utilizator. Adăugați formularul la add.jsp . Ar trebui să conțină două câmpuri de introducere a textului (unul obișnuit, celălalt - un câmp de parolă) și un buton pentru trimiterea datelor către server.

<form method="post">
    <label>Name:
        <input type="text" name="name"><br />
    </label>

    <label>Password:
        <input type="password" name="pass"><br />
    </label>
    <button type="submit">Submit</button>
</form>
Aici formularul are un atribut de metodă cu valoarea post . Aceasta indică faptul că datele din acest formular vor ajunge la server ca cerere POST . Atributul de acțiune nu este specificat, ceea ce înseamnă că solicitarea va fi trimisă la aceeași adresă de la care am ajuns la această pagină ( /add ). Astfel, la primirea unei cereri GET , servletul nostru legat la această adresă returnează JSP- ul cu formularul de adăugare de utilizator. Și dacă primește o cerere POST , atunci știm că formularul și-a trimis datele aici (pe care le extragem din obiectul de solicitare dindoPost()metoda, proces și trece la model pentru salvare). Este de remarcat faptul că câmpurile de intrare au un parametru numit nume (pentru nume de utilizator sau trecere pentru parole). Acesta este un punct foarte important. Astfel, pentru a primi aceste date (numele de utilizator și parola care vor fi introduse) din cerere (în interiorul servlet-ului), vom folosi aceste câmpuri de nume și de trecere . Dar mai multe despre asta mai târziu. Butonul meu pentru trimiterea datelor a fost din nou făcut ca un buton , nu ca un câmp de ieșire, așa cum este obișnuit. Nu știu cât de larg adoptată este această abordare, dar funcționează pentru mine (browserul Chrome).

Gestionarea servlet-urilor cererilor POST

Să revenim la AddServlet . Vă reamintesc că pentru a permite servlet-ului nostru să „prindă” solicitările GET , am suprascris doGet()metoda din clasa HttpServlet . Pentru a învăța servlet-ul nostru să capteze și cererile POST , trebuie, de asemenea, să suprascriem doPost()metoda. Tomcat îi transmite obiecte de cerere și răspuns similare cu care vom lucra. Pentru a începe, extrageți numele cererii și treceți parametrii trimiși de formular (dacă ați specificat nume diferite în formular, atunci utilizați acele nume). După aceea, creați un obiect utilizator folosind datele primite. Apoi obținem obiectul model și adăugăm utilizatorul creat la model.

@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);
}

Trecerea datelor către vizualizare

Să trecem la ListServlet . Metoda doGet()este deja implementată. Pur și simplu transferă controlul către vizualizare ( list.jsp ). Dacă nu aveți încă acest lucru, atunci creați-l prin analogie cu metoda din AddServlet . Acum ar fi bine să obțineți lista de nume de utilizator de pe model și să le treceți la vizualizare, care le va primi și le va afișa frumos. Pentru a face acest lucru, vom folosi din nou obiectul de solicitare primit de la Tomcat . Putem adăuga un atribut acestui obiect, dându-i un fel de nume. De fapt, putem adăuga obiectul pe care vrem să-l transmitem în vizualizare. Datorită faptului că atunci când transferăm controlul de la servlet la vizualizare, transmitem vizualizării aceleași obiecte de cerere și răspuns pe care le-a primit servletul, putem adăuga lista noastră de nume la obiectul de solicitare și apoi obținem lista noastră de nume de utilizator din cerere. obiect în vedere. Am terminat cu clasa ListServlet , așa că voi prezenta aici codul întregii clase:

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<String> names = model.list();
        req.setAttribute("userNames", names);

        RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/list.jsp");
        requestDispatcher.forward(req, resp);
    }
}

Rularea cod Java în fișiere JSP

Este timpul să vă uitați la list.jsp . Acesta va fi executat numai când ListServlet îi transferă controlul. În plus, am pregătit deja lista de nume de utilizator din model în servlet și am trecut-o aici în obiectul de solicitare. Deoarece avem lista de nume, putem itera peste ea folosind o forbuclă și afișăm fiecare nume. După cum am spus mai devreme, fișierele JSP pot executa cod Java (care este ceea ce le face diferite de paginile HTML statice). Pentru a executa un cod, tot ce trebuie să facem este să punem următorul construct în locul potrivit:

<!-- html code -->
<%
    // Java code
%>
<!-- html code -->
În cadrul acestui construct, obținem acces la mai multe variabile:
  • request — obiectul nostru cerere, pe care l-am transmis de la servlet, unde a fost numit pur și simplu req ;
  • răspuns — obiectul răspuns (numit resp în servlet);
  • out — un obiect JspWriter (care moștenește un Writer obișnuit ), pe care îl putem folosi pentru a „scrie” ceva direct în pagina HTML însăși. Declarația out.println("Bună, Lume!") este foarte asemănătoare cu System.out.println("Bună, Lume!") , dar nu le confundați!
  • out.println() „scrie” într-o pagină HTML , în timp ce System.out.println scrie în fluxul de ieșire a sistemului . Dacă apelați System.out.println() într-o secțiune JSP cu cod Java , veți vedea rezultatele în consola Tomcat , dar nu și pe pagină.
Puteți căuta alte obiecte disponibile într-un JSP aici . Putem folosi obiectul request pentru a obține lista de nume transmise de la servlet (am atașat atributul corespunzător acestui obiect) și vom folosi obiectul out pentru a afișa aceste nume. Să le afișăm (deocamdată, ca o simplă listă HTML):

<ul>
    <%
        List<String> names = (List<String>) request.getAttribute("userNames");

        if (names != null && !names.isEmpty()) {
            for (String s : names) {
                out.println("<li>" + s + "</li>");
            }
        }
    %>
</ul>
Dacă trebuie să afișăm lista numai dacă există utilizatori și, în caz contrar, afișăm un avertisment că nu există încă utilizatori, atunci putem rescrie puțin această secțiune:

<%
    List<String> names = (List<String>) request.getAttribute("userNames");

    if (names != null && !names.isEmpty()) {
        out.println("<ui>");
        for (String s : names) {
            out.println("<li>" + s + "</li>");
        }
        out.println("</ui>");
    } else out.println("<p>There are no users yet!</p>");
%>
Acum că știm cum să transmitem date de la servlet-uri la vizualizări, putem îmbunătăți AddServlet- ul , astfel încât să afișeze o notificare despre adăugarea cu succes a unui utilizator. Pentru a face acest lucru, în doPost()metodă, după adăugarea unui nou utilizator la model, putem adăuga acest nume de utilizator la atributele obiectului req și trece controlul înapoi la o vizualizare ( add.jsp ). Și acum vom adăuga o secțiune cu cod Java, unde vom verifica dacă cererea are un astfel de atribut și, dacă are, atunci vom afișa un mesaj că utilizatorul a fost adăugat cu succes. După aceste modificări, codul complet al lui AddServlet va arăta cam așa:

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);
    }
}
Aici, la sfârșitul metodei, doPost()creăm un atribut cu numele utilizatorului care a fost adăugat la model, apoi apelăm metoda doGet(), căreia îi transmitem cererea și răspunsul curent. Metoda doGet()transferă acum controlul către vizualizare, care primește și obiectul de solicitare cu numele utilizatorului adăugat atașat ca atribut. Ceea ce ne rămâne de făcut este să reparăm add.jsp , astfel încât să afișeze notificarea dacă nu există un astfel de atribut. Iată versiunea finală a add.jsp :

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

    <body>
        <div>
            <h1>Super app!</h1>
        </div>

        <div>
            <%
                if (request.getAttribute("userName") != null) {
                    out.println("<p>User '" + request.getAttribute("userName") + "' added!</p>");
                }
            %>
            <div>
                <div>
                    <h2>Add user</h2>
                </div>

                <form method="post">
                    <label>Name:
                        <input type="text" name="name"><br />
                    </label>
                    <label>Password:
                        <input type="password" name="pass"><br />
                    </label>
                    <button type="submit">Submit</button>
                </form>
            </div>
        </div>

        <div>
            <button onclick="location.href='/'">Back to main</button>
        </div>
    </body>
</html>
Corpul paginii este format din următoarele:
  • un div cu antet;
  • un container div pentru conținut, care include o verificare dacă există un atribut cu un nume de utilizator;
  • un div cu formularul add-user;
  • iar în partea de jos, un subsol cu ​​un buton pentru a reveni la pagina de pornire.
Poate părea prea multe div-uri, dar le vom folosi mai târziu când vom adăuga stiluri. Iată versiunea finală a list.jsp :

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

    <body>
        <div>
            <h1>Super app!</h1>
        </div>

        <div>
            <div>
                <div>
                    <h2>Users</h2>
                </div>
                <%
                    List<String> names = (List<String>) request.getAttribute("userNames");

                    if (names != null && !names.isEmpty()) {
                        out.println("<ui>");
                        for (String s : names) {
                            out.println("<li>" + s + "</li>");
                        }
                        out.println("</ui>");
                    } else out.println("<p>There are no users yet!</p>");
                %>
            </div>
        </div>

        <div>
            <button onclick="location.href='/'">Back to main</button>
        </div>
    </body>
</html>
Astfel, avem o aplicație web complet funcțională, care poate salva și adăuga utilizatori și, de asemenea, poate afișa o listă cu numele acestora. Acum trebuie doar să-l facem frumos... :) Crearea unei aplicații web simple folosind servlet-uri și JSP-uri (partea 2) - 2

Adăugarea de stiluri. Vom folosi cadrul W3.CSS

Momentan, aplicația noastră funcționează, dar pare absolut revoltătoare. Deci, să adăugăm un fundal, să colorăm textul și butoanele, să adăugăm stil listelor, să aliniem elementele, să adăugăm indentări și așa mai departe. Scrierea manuală a stilurilor poate dura mult timp și ne poate solicita nervii. Așa că propun utilizarea cadrului W3.CSS . Are deja clase gata de utilizare cu stiluri. Trebuie doar să aranjam clasele CSS pe care dorim să le folosim în locurile potrivite. Pentru a le adăuga la paginile noastre, conectăm mai întâi fișierul de stil. Există două moduri de a face acest lucru:
  1. parcurgeți paginile noastre și introduceți următorul link direct către fișierul de stil în secțiunea de cap

    <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">

    Această opțiune este potrivită dacă aveți o conexiune permanentă la Internet. Când deschideți paginile pe serverul local, stilurile vor fi extrase de pe Internet.

  2. Dar dacă doriți să aveți toate stilurile la nivel local și să nu depindeți de o conexiune la Internet, descărcați fișierul de stil și plasați-l undeva în folderul web ( ex. web/styles/w3.css ). Apoi parcurgeți toate paginile noastre ( index.html, add.jsp, list.jsp ) și adăugați următorul link la fișierul de stil din interiorul secțiunii head :

    <link rel="stylesheet" href="styles/w3.css">

    După aceea, parcurgeți etichetele și adăugați stilurile care vă plac. Nu mă voi opri asupra acestui lucru în detaliu. În schimb, voi oferi doar versiuni gata de utilizare a trei dintre fișierele mele cu clase în stil raster.

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Super app!</title>
        <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    </head>

    <body class="w3-light-grey">
        <div class="w3-container w3-blue-grey w3-opacity w3-right-align">
            <h1>Super app!</h1>
        </div>

        <div class="w3-container w3-center">
            <div class="w3-bar w3-padding-large w3-padding-24">
                <button class="w3-btn w3-hover-light-blue w3-round-large" onclick="location.href='/list'">List users</button>
                <button class="w3-btn w3-hover-green w3-round-large" onclick="location.href='/add'">Add user</button>
            </div>
        </div>
    </body>
</html>
add.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Add new user</title>
        <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    </head>

    <body class="w3-light-grey">
        <div class="w3-container w3-blue-grey w3-opacity w3-right-align">
            <h1>Super app!</h1>
        </div>

        <div class="w3-container w3-padding">
            <%
                if (request.getAttribute("userName") != null) {
                    out.println("<div class=\"w3-panel w3-green w3-display-container w3-card-4 w3-round\">\n" +
                            "   <span onclick=\"this.parentElement.style.display='none'\"\n" +
                            "   class=\"w3-button w3-margin-right w3-display-right w3-round-large w3-hover-green w3-border w3-border-green w3-hover-border-grey\">×</span>\n" +
                            "   <h5>User '" + request.getAttribute("userName") + "' added!</h5>\n" +
                            "</div>");
                }
            %>
            <div class="w3-card-4">
                <div class="w3-container w3-center w3-green">
                    <h2>Add user</h2>
                </div>
                <form method="post" class="w3-selection w3-light-grey w3-padding">
                    <label>Name:
                        <input type="text" name="name" class="w3-input w3-animate-input w3-border w3-round-large" style="width: 30%"><br />
                    </label>
                    <label>Password:
                        <input type="password" name="pass" class="w3-input w3-animate-input w3-border w3-round-large" style="width: 30%"><br />
                    </label>
                    <button type="submit" class="w3-btn w3-green w3-round-large w3-margin-bottom">Submit</button>
                </form>
            </div>
        </div>

        <div class="w3-container w3-grey w3-opacity w3-right-align w3-padding">
            <button class="w3-btn w3-round-large" onclick="location.href='/'">Back to main</button>
        </div>
    </body>
</html>
list.jsp

<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Users list</title>
        <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    </head>

    <body class="w3-light-grey">
        <div class="w3-container w3-blue-grey w3-opacity w3-right-align">
            <h1>Super app!</h1>
        </div>

        <div class="w3-container w3-center w3-margin-bottom w3-padding">
            <div class="w3-card-4">
                <div class="w3-container w3-light-blue">
                    <h2>Users</h2>
                </div>
                <%
                    List<String> names = (List<String>) request.getAttribute("userNames");

                    if (names != null && !names.isEmpty()) {
                        out.println("<ul class=\"w3-ul\">");
                        for (String s : names) {
                            out.println("<li class=\"w3-hover-sand\">" + s + "</li>");
                        }
                        out.println("</ul>");

                    } else out.println("<div class=\"w3-panel w3-red w3-display-container w3-card-4 w3-round\">\n"
+
                            "   <span onclick=\"this.parentElement.style.display='none'\"\n" +
                            "   class=\"w3-button w3-margin-right w3-display-right w3-round-large w3-hover-red w3-border w3-border-red w3-hover-border-grey\">×</span>\n" +
                            "   <h5>There are no users yet!</h5>\n" +
                            "</div>");
                %>
            </div>
        </div>

        <div class="w3-container w3-grey w3-opacity w3-right-align w3-padding">
            <button class="w3-btn w3-round-large" onclick="location.href='/'">Back to main</button>
        </div>
    </body>
</html>
Si asta e. :) Dacă mai aveți întrebări sau comentarii, sau dacă ceva nu merge, vă rugăm să lăsați un comentariu. Și voi atașa câteva capturi de ecran cu cum a ieșit totul.
Crearea unei aplicații web simple folosind servlet-uri și JSP-uri (partea 2) - 3
Crearea unei aplicații web simple folosind servlet-uri și JSP-uri (partea 2) - 4
Crearea unei aplicații web simple folosind servlet-uri și JSP-uri (partea 2) - 5
Și, în sfârșit , dacă doriți să exersați cu acest proiect, puteți încerca următoarele:
  • faceți un servlet și JSP pentru a șterge un utilizator și adăugați o altă pereche pentru a edita un utilizator existent. Rezultatul va fi o aplicație web CRUD autentică, construită folosind servlet-uri. ;)
  • înlocuiți Lista cu o bază de date, astfel încât utilizatorii adăugați să nu dispară după repornirea serverului. :)
Noroc!
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION