CodeGym/Java блог/Случаен/Създаване на просто уеб приложение с помощта на сървлети ...
John Squirrels
Ниво
San Francisco

Създаване на просто уеб приложение с помощта на сървлети и JSP (част 2)

Публикувано в групата
Създаване на просто уеб приложение с помощта на сървлети и JSP (част 1) Знания, необходими за разбиране на статията: Вече сте повече or по-малко разбрали Java Core и бихте искали да разгледате JavaEE технологиите и уеб програмирането. Би било най-разумно в момента да изучавате мисията Java Collections, която се занимава с теми, близки до статията.
Създаване на просто уеб приложение с помощта на сървлети и JSP (част 2) - 1

Създаване на обекти

В пакета entities ще създадем Userклас, който има две частни низови променливи: име и парола . Създайте конструктори (по подразбиране и такъв, който приема и двете стойности) и getters/setter и заменете метода toString()за всеки случай, заедно с equals()and hashCode()методите. С други думи, ние ще направим всичко, което прави уважаван Java разработчик, когато създава клас.
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;
    }
}
Сега можем да започнем да създаваме списък с потребители. Ще добавим потребители към него и ще вземем потребители от него, за да ги покажем. Имаме обаче един проблем. Ние не създаваме нашите сървлет обекти. Tomcat прави това за нас. Методите, които заместваме в тях, вече са дефинирани за нас и не можем да параметрираме. Как тогава да създадем споделен списък, който ще бъде видим и в двата ни сервлета? Ако просто създадем обект от списък във всеки сървлет, тогава ще добавяме потребители към един списък, но ще показваме потребители от друг в ListServlet. Така че имаме нужда от обект, който се споделя от двата сървлета. Най-общо казано, имаме нужда от обект, който се споделя от всички класове в нашата програма: един обект за цялата програма. Надявам се, че сте чували нещо за дизайнерските модели. За някои хора това може да е първата реална нужда от модела Singleton в тяхната програма. Бихте могли да станете откачени и да извадите някой сладък Singleton с двойни проверки и синхронизация (да, нашето приложение е многонишково, тъй като сървлетите Tomcat работят на отделни нишки). Но ще използвам техниката за ранна инициализация, защото е напълно подходяща за нашите цели тук.

Създаване на модел

Създайте клас (и имплементирайте модела Singleton ) в пакета на модела и го наречете нещо необичайно. Например, Модел . Ще създадем частен списък с потребители в нашия клас и ще приложим два метода: един за добавяне на потребител и друг за връщане на списък от низове (потребителски имена). Тъй като нашият потребителски обект се състои от потребителско име и парола и не искаме да разкриваме потребителски пароли, ще имаме само списък с имена.
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());
    }
}

Малко за MVC

Тъй като вече сте чували за singleton , вероятно сте чували и за друг шаблон за проектиране модел-изглед-контролер (MVC). Целта му е да отдели бизнес логиката от изгледа. Тоест, да се отдели codeът, който определя Howво да се прави от codeа, който определя How да се показват нещата. Изгледът е отговорен за това How се представят данните. В нашия случай изгледите са нашите JSP страници . Точно затова ги сложих в папка с име views . Моделът са данните, с които програмата действително работи. В нашия случай това са потребителите (списък с потребители). А контролерите са връзката между тях. Те вземат данни от модела и ги предават на изгледите (or получават някои данни от Tomcat, обработете го и го предайте на модела). Вие определяте вашата бизнес логика (Howво трябва да прави програмата) в тях, а не в модела or изгледа. Така всяка част се справя със собствения си бизнес:
  • моделът съхранява данни;
  • изгледите правят красиво представяне на данните;
  • администраторите обработват данните.
Това позволява на програмата да бъде доста проста и поддържаема, а не чудовищна купчина от целия code в един клас. MVC е подходящ не само за уеб програмиране, но се използва особено често в тази област (почти винаги). В нашия случай сървлетите ще действат като контролери. Това е много повърхностно и кратко описание на модела, но MVC не е основната тема на тази статия. Ако някой иска да научи повече, Google е ваш приятел! Създайте формуляр за добавяне на потребител. Добавете формуляра към add.jsp . Той трябва да се състои от две полета за въвеждане на текст (едното обикновено, другото — поле за парола) и бутон за изпращане на данните към сървъра.
<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>
Тук формулярът има атрибут на метод със стойност post . Това показва, че данните от този формуляр ще отидат на сървъра като POST заявка . Атрибутът за действие не е посочен, което означава, че заявката ще бъде изпратена на същия address, от който сме стигнали до тази page ( /add ). По този начин, при получаване на GET заявка , нашият сървлет, свързан към този address, връща JSP с формуляра за добавяне на потребител. И ако получи POST заявка , тогава знаем, че формулярът е изпратил своите данни тук (които извличаме от обекта на заявката вdoPost()метод, процес и преминаване към модела за запис). Струва си да се отбележи, че полетата за въвеждане имат параметър, наречен име (за потребителски имена or пропуск за пароли). Това е много важен момент. По този начин, за да получим тези данни (потребителското име и паролата, които ще бъдат въведени) от заявката (вътре в сървлета), ще използваме тези полета за име и пропуск . Но повече за това по-късно. Моят бутон за изпращане на данни отново беше напequals като бутон , а не като изходно поле, Howто е обичайно. Не знам колко широко е възприет този подход, но работи за мен (браузър Chrome).

Сервлет обработка на POST заявки

Да се ​​върнем към AddServlet . Напомням ви, че за да позволим на нашия сървлет да "хваща" GET заявки , ние отменихме doGet()метода в класа HttpServlet . За да научим нашия сървлет също да улавя POST заявки , трябва също така да заменим doPost()метода. Tomcat му предава подобни обекти за заявка и отговор, с които ще работим. За да започнете, извлечете името на заявката и подайте параметрите, изпратени от формуляра (ако сте посочor различни имена във формуляра, използвайте тези имена). След това създайте потребителски обект, използвайки получените данни. След това получаваме моделния обект и добавяме създадения потребител към модела.
@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);
}

Предаване на данни към изгледа

Нека да преминем към ListServlet . Методът doGet()вече е внедрен. Той просто прехвърля контрола върху изгледа ( list.jsp ). Ако все още нямате това, създайте го по аналогия с метода в AddServlet . Сега би било хубаво да вземете списъка с потребителски имена от модела и да ги предадете на изгледа, който ще ги получи и ще ги покаже красиво. За да направим това, отново ще използваме обекта на заявката, който получихме от Tomcat . Можем да добавим атрибут към този обект, давайки му няHowво име. Всъщност можем да добавим обекта, който искаме да предадем към изгледа. Поради факта, че когато прехвърляме контрола от сървлета към изгледа, ние предаваме на изгледа същите обекти за заявка и отговор, които сервлетът е получил, можем да добавим нашия списък с имена към обекта за заявка и след това да получим нашия списък с потребителски имена от заявката обект в изгледа. Приключихме с класа ListServlet , така че ще представя codeа на целия клас тук:
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);
    }
}

Изпълнение на Java code в JSP файлове

Време е да разгледаме list.jsp . Той ще бъде изпълнен само когато ListServlet прехвърли контрол върху него. Освен това вече подготвихме списъка с потребителски имена от модела в сървлета и го предадохме тук в обекта на заявката. Тъй като имаме списъка с имена, можем да го обикаляме с помощта на forцикъл и да показваме всяко име. Както казах преди, JSP файловете могат да изпълняват Java code (което ги прави различни от статичните HTML страници). За да изпълним няHowъв code, всичко, което трябва да направим, е да поставим следната конструкция на подходящото място:
<!-- html code -->
<%
    // Java code
%>
<!-- html code -->
В рамките на тази конструкция получаваме достъп до няколко променливи:
  • заявка — нашия обект на заявка, който предадохме от сървлета, където беше просто извикан req ;
  • отговор — обектът на отговор (наречен resp в сървлета);
  • outJspWriter обект (който наследява обикновен Writer ), който можем да използваме, за да "напишем" нещо директно в самата HTML page . Изявлението out.println("Hello, World!") е много подобно на System.out.println("Hello, World!") , но не ги бъркайте!
  • out.println() "пише" в HTML page , докато System.out.println пише в системния изходен поток . Ако извикате System.out.println() в JSP секция с Java code , ще видите резултатите в конзолата Tomcat , но не и на pageта.
Можете да търсите други обекти, налични в JSP тук . Можем да използваме обекта на заявката , за да получим списъка с имена, предадени от сървлета (ние прикачихме съответния атрибут към този обект), и получаваме използване на обекта out , за да покаже тези имена. Нека ги покажем (за момента като обикновен 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>
Ако трябва да покажем списъка само ако има потребители и в противен случай да покажем предупреждение, че все още няма потребители, тогава можем да пренапишем малко този раздел:
<%
    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>");
%>
След като вече знаем How да предаваме данни от сървлети към изгледи, можем да подобрим нашия AddServlet , така че да показва известие за успешното добавяне на потребител. За да направим това, в doPost()метода, след добавяне на нов потребител към модела, можем да добавим това потребителско име към атрибутите на обекта req и да предадем контрола обратно на изглед ( add.jsp ). И сега ще добавим към него раздел с Java code, където ще проверим дали заявката има такъв атрибут и ако има — ще изведем съобщение, че потребителят е добавен успешно. След тези промени пълният code на AddServlet ще изглежда така:
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);
    }
}
Тук в края на doPost()метода създаваме атрибут с името на потребителя, който е добавен към модела, след което извикваме метода doGet(), на който предаваме текущата заявка и отговор. Сега методът doGet()прехвърля контрола към изгледа, който също получава обекта на заявката с името на добавения потребител, прикачен като атрибут. Това, което остава да направим, е да коригираме add.jsp, така че да показва известието, ако няма такъв атрибут. Ето окончателната version на 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>
Основният текст на pageта се състои от следното:
  • div със заглавка;
  • div контейнер за съдържание, който включва проверка дали съществува атрибут с потребителско име;
  • div с формуляра за добавяне на потребител;
  • и в долната част долен колонтитул с бутон за връщане към началната page.
Това може да изглежда като твърде много div, но ще ги използваме по-късно, когато добавяме стилове. Ето окончателната version на 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>
Така имаме напълно работещо уеб приложение, което може да записва и добавя потребители, Howто и да показва списък с техните имена. Сега просто трябва да го направим красив... :) Създаване на просто уеб приложение с помощта на сървлети и JSP (част 2) - 2

Добавяне на стилове. Ще използваме рамката W3.CSS

В момента нашето приложение работи, но изглежда абсолютно безобразно. И така, нека добавим фон, оцветим текста и бутоните, добавим стил към списъците, подравним елементи, добавим отстъпи и т.н. Ръчното писане на стилове може да отнеме много време и да изнерви нервите ни. Затова предлагам да използвате рамката W3.CSS . Вече има готови за използване класове със стилове. Просто трябва да подредим CSS класовете, които искаме да използваме, на правилните места. За да ги добавим към нашите страници, първо свързваме стиловия файл. Има два начина да направите това:
  1. прегледайте нашите страници и вмъкнете следната директна връзка към стиловия файл в секцията head

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

    Тази опция е подходяща, ако имате постоянна интернет връзка. Когато отворите страниците си на локалния сървър, стиловете ще бъдат изтеглени от Интернет.

  2. Но ако искате да имате всички стилове локално и да не зависи от интернет връзка, изтеглете стиловия файл и го поставете някъде в уеб папката (напр. web/styles/w3.css ). След това преминете през всички наши страници ( index.html, add.jsp, list.jsp ) и добавете следната връзка към стиловия файл в секцията head :

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

    След това просто прегледайте етикетите и добавете стиловете, които харесвате. Няма да се спирам подробно на това. Вместо това просто ще предоставя готови за използване версии на три от моите файлове с класове в растерен стил.

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>
И това е. :) Ако все още имате няHowви въпроси or коментари, or ако нещо не се получава, моля, оставете коментар. И ще прикача няколко екранни снимки за това How се оказа всичко.
Създаване на просто уеб приложение с помощта на сървлети и JSP (част 2) - 3
Създаване на просто уеб приложение с помощта на сървлети и JSP (част 2) - 4
Създаване на просто уеб приложение с помощта на сървлети и JSP (част 2) - 5
И накрая , ако искате да практикувате с този проект, можете да опитате следното:
  • направете сървлет и JSP за изтриване на потребител и добавете друга двойка за редактиране на съществуващ потребител. Резултатът ще бъде истинско CRUD уеб приложение, създадено с помощта на сървлети. ;)
  • заменете списъка с база данни, така че добавените потребители да не изчезнат след рестартиране на сървъра. :)
Късмет!
Коментари
  • Популярен
  • Нов
  • Стар
Трябва да сте влезли, за да оставите коментар
Тази страница все още няма коментари