JavaRush /Blog Java /Random-PL /Twoja pierwsza aplikacja korzystająca z serwletów Java

Twoja pierwsza aplikacja korzystająca z serwletów Java

Opublikowano w grupie Random-PL
Cześć wszystkim! W tym artykule zapoznasz się z podstawową koncepcją programowania serwletów i będziesz w stanie napisać przy ich użyciu prostą aplikację. Twoja pierwsza aplikacja korzystająca z serwletów Java — 1Aby uniknąć niepotrzebnych kroków, nie będziemy zaczynać od zera i będziemy kontynuować prace nad naszą aplikacją z mojego poprzedniego artykułu o Hibernacji . Ponieważ jednak dopiero zaczynamy pracę z serwletami, usunąłem z aplikacji wszystko, co dotyczy klasy Auto, pozostawiając jedynie klasę User i jej akcje. Struktura projektu będzie wyglądać następująco: Twoja pierwsza aplikacja korzystająca z serwletów Java - 2A więc serwlety! Wikipedia podaje: „Serwlet to interfejs Java, którego implementacja rozszerza funkcjonalność serwera. Serwlet współdziała z klientami na zasadzie żądanie-odpowiedź”. I rzeczywiście tak jest. Tutaj po raz pierwszy spotykamy się z koncepcją „architektury aplikacji klient-serwer”. Jego istota jest dość prosta i mieści się w jednym obrazie (zaczerpniętym stąd ).
Twoja pierwsza aplikacja korzystająca z serwletów Java — 3
Klient kontaktuje się z serwerem wysyłając żądanie HTTP. Serwer generuje niezbędne dane (np. pobiera je z bazy danych) i zwraca je klientowi. Najprostszy przykład: w określonej sieci społecznościowej klikasz przycisk „Znajomi” i w ten sposób wysyłasz żądanie do serwera. Serwer sprawdza listę Twoich znajomych w bazie danych i zwraca ją Tobie (klientowi). Lista żądań HTTP jest dość duża, jeśli jednak nigdy się z nimi nie spotkałeś, to dla lepszego zrozumienia lepiej o nich poczytać np. tutaj . Naszym zadaniem jest: Utworzenie aplikacji CRUD z wykorzystaniem serwletów. Aplikacja musi mieć możliwość tworzenia, modyfikowania i usuwania użytkowników z bazy danych przy użyciu serwletu przetwarzającego żądania HTTP. Nasza aplikacja z artykułu o Hibernate już wiedziała, jak to zrobić, ale sterowana była bezpośrednio z kodu Java, a dokładniej z metody main(). Tutaj żądania będą wysyłane przez klienta, czyli Ciebie :) Pierwszą rzeczą, którą musimy zrobić, to dodać nowe zależności do naszego pliku pom.xml
<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>com.itis4</groupId>
    <artifactId>UsersDaoProject</artifactId>
    <version>1.0-SNAPSHOT</version>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <!-- PostgreSQL  -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.4.1212.jre7</version>
        </dependency>

        <!-- Hibernate 5.2.6 Final -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.6.Final</version>
        </dependency>

        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.4.RELEASE</version>
        </dependency>

    </dependencies>

</project>
Dodaliśmy 3 zależności:
  1. Sama biblioteka javax.servlet-api;
  2. Biblioteka znaczników JSTL. Konieczne będzie utworzenie strony klienta, a mianowicie stron JSP;
  3. Spring-WebMVC. Będziemy potrzebować jednej klasy wiosennej, o której porozmawiamy nieco później.
Działaniem serwletów zarządza kontener serwletów. W naszym przypadku użyjemy Apache Tomcat. Całkiem popularna rzecz i pewnie już o niej słyszałeś :) Cykl życia serwletu składa się z następujących kroków:
  1. Jeśli w kontenerze nie ma serwletu.
    • Klasa serwletu jest ładowana przez kontener.
    • Kontener tworzy instancję klasy serwletu.
    • Kontener wywołuje metodę init(). Metoda ta inicjuje serwlet i jest wywoływana zanim serwlet będzie mógł obsłużyć żądania. Metoda init() jest wywoływana tylko raz w całym cyklu życia.
  2. Obsługa żądania klienta. Każde żądanie jest przetwarzane w osobnym wątku. Kontener wywołuje metodę service() dla każdego żądania. Metoda ta określa typ przychodzącego żądania i przekazuje go metodzie odpowiadającej temu typowi w celu przetworzenia żądania. Twórca serwletu musi zapewnić implementacje tych metod. W przypadku otrzymania żądania, dla którego nie zaimplementowano metody, wywoływana jest metoda klasy nadrzędnej, co zwykle kończy się zwróceniem błędu do requestera.
  3. W przypadku, gdy kontener musi usunąć serwlet, wywołuje metodęzniszcz(), która usuwa serwlet z usługi. Podobnie jak metoda init(), ta metoda jest również wywoływana raz podczas całego cyklu serwletu.
Nasz serwlet będzie wyglądał całkiem prosto:
package servlets;

import models.User;
import services.UserService;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
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 UserSimpleServlet extends HttpServlet {

    private UserService service = new UserService();

    public void init(ServletConfig servletConfig) {
        try {
            super.init(servletConfig);
        } catch (ServletException e) {
            e.printStackTrace();
        }
    }

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

        List<User> users = service.findAllUsers();
        req.setAttribute("users", users);
        RequestDispatcher dispatcher = req.getRequestDispatcher("/showUsers.jsp");
        dispatcher.forward(req, resp);

    }

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

        String name = req.getParameter("name");
        int age = Integer.parseInt(req.getParameter("age"));
        User user = new User(name, age);
        service.saveUser(user);
        resp.sendRedirect("/users");

    }

    @Override
    protected void  doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int id = Integer.parseInt(req.getParameter("id"));
        User user = service.findUser(id);
        user.setName(req.getParameter("name"));
        user.setAge(Integer.parseInt(req.getParameter("age")));
        service.updateUser(user);
        resp.sendRedirect("/users");
    }

    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        int id = Integer.parseInt(req.getParameter("id"));
        service.deleteUser(service.findUser(id));
        resp.sendRedirect("/users");
    }
}
Jak widać zawiera opisaną powyżej metodę init() oraz implementuje 4 metody pokrywające się z czterema żądaniami HTTP - doGet(), doPost(), doPut() i doDelete(). Każdy z nich pozwoli nam odpowiednio przyjmować, tworzyć, edytować i usuwać użytkowników. Metody przyjmują jako obiekty wejściowe klasy javax.servlet.http.HttpServletRequest i javax.servlet.http.HttpServletResponse – czyli żądanie wysłane do serwera i odpowiedź otrzymaną przez klienta. Wewnątrz metod wykonywane są niezbędne metody klasy UserService, generowana jest odpowiedź dla klienta, a następnie przekierowywana na adres /users. Przykładowo w metodzie doGet() otrzymujemy listę wszystkich użytkowników. Następnie tworzymy obiekt klasy RequestDispatcher, który pozwala na załączenie obiektów w żądaniu Http, a także przekierowanie go do konkretnego zasobu (na przykład strony JSP klienta). W metodzie doPut() (aktualizacja danych użytkownika) przetwarzamy żądanie HTTP, wyciągamy z niego parametry id, name i age, odnajdujemy użytkownika o podanym id, przypisujemy mu imię i wiek, które otrzymał w żądanie i wróć do strony /users. Aby jednak wszystkie te metody działały poprawnie, musimy skonfigurować serwlet. Wykorzystujemy do tego plik web.xml znajdujący się w folderze WEB-INF.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1"
         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">

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>UserSimpleServlet</servlet-name>
        <servlet-class>servlets.UserSimpleServlet</servlet-class>
    </servlet>

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

    <filter>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <servlet-name>UserSimpleServlet</servlet-name>
    </filter-mapping>

</web-app>
Wszystkie tagi w tym pliku są w zasadzie intuicyjne, ale przejrzyjmy je po kolei. <lista-plików-powitalnych> - określona jest początkowa strona JSP, która zostanie otwarta jako pierwsza po uruchomieniu aplikacji. W naszym przypadku jest to strona Index.jsp. <servlet> - rejestracja naszej klasy UserSimpleServlet jako serwletu. <servlet-mapping> jest bardzo ważnym znacznikiem. Definiuje adresy URL, które będą przetwarzane przez serwlet. W naszym przypadku są to wszystkie adresy URL, dlatego po prostu wskazujemy „/”. Ale na przykład gdybyśmy mieli aplikację z użytkownikami i ich maszynami, moglibyśmy stworzyć drugi serwlet - SimpleAutoServlet. Następnie mapowaniem serwletu użytkownika byłoby „/users” (to znaczy żądań związanych z przetwarzaniem użytkowników), a dla serwletu automatycznego byłoby to „/autos”. I na koniec <filtr>. Definiuje wewnętrznie obiekt klasy org.springframework.web.filter.HiddenHttpMethodFilter. Artykuł nie dotyczy wiosny, więc nie będę się nad nią szczegółowo rozwodzić. Powiem tylko, że jest on dołączony do naszej aplikacji jedynie jako dodatkowa funkcja. Chodzi o to, że do stworzenia strony klienta użyjemy stron JSP. Nasze dane zostaną wyświetlone na stronie w postaci tabeli z listą użytkowników. Wewnątrz stron JSP używane będą znaczniki HTML <form/>. Do wysyłania danych z <form/> można używać wyłącznie żądań HTTP GET i POST. Oznacza to, że dla wszystkich trzech operacji – aktualizacji, usuwania i tworzenia użytkownika – musielibyśmy używać wyłącznie żądań POST. Korzystanie z żądań PUT i DELETE nie byłoby dla nas możliwe. I w zasadzie jest to całkiem normalne i łatwe do wdrożenia, ale klasa HiddenHttpMethodFilter pozwala nam z nich skorzystać. Dzięki temu różnice pomiędzy operacjami w aplikacji będą bardziej zrozumiałe dla czytelnika. Na koniec przejdźmy do strony klienta. Jest reprezentowany przez pięć stron JSP. indeks.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Здравствуйте!</title>
</head>
<body>
Если вы хотите начать работу с базой данных пользователей - <br>
нажмите кнопку ниже:

<form action = "users" method="get">
    <input type="submit" value="Начать работу с базой данных">
</form>
</body>
</html>
dodajUżytkownika.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Добавить нового пользователя</title>
</head>
<body>
<form action = "/users" method="post">
    <input required type="text" name="name" placeholder="Nazwa">
    <input required type="text" name="age" placeholder="Возраст">
    <input type="submit" value="Сохранить">
</form>
</body>
</html>
usuńUser.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Удалить пользователя</title>
</head>
<body>

Вы действительно хотите удалить пользователя ${param.id}?

&lform action="/users/${param.id}" method="post">
    <input type="hidden" name="id" value="${param.id}">
    <input type="hidden" name="_method" value="delete">
    <input type="submit" value="Удалить">
</form>

</body>
</html>
showUsers.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Список пользователей</title>
</head>
<body>
<table border="2">
    <tr>
        <td>ID</td>
        <td>Nazwa</td>
        <td>Возраст</td>
        <td>Действия</td>
    </tr>
    <c:forEach items="${users}" var = "user">
        <tr>
            <td>${user.getId()}</td>
            <td>${user.getName()}</td>
            <td>${user.getAge()}</td>
            <td>
                <form action = "updateUser.jsp" method="post">
                    <input type="hidden" name="id" value="${user.getId()}">
                    <input type="hidden" name="name" value="${user.getName()}">
                    <input type="hidden" name="age" value="${user.getAge()}">
                    <input type="submit" value="Изменить" style="float:left">
                </form>
                <form action="deleteUser.jsp" method="post">
                    <input type="hidden" name="id" value="${user.getId()}">
                    <input type="submit" value="Удалить" style="float:left">
                </form></td>
        </tr>
    </c:forEach>
</table>

<form action = "addUser.jsp">
    <input type="submit" value="Добавить нового пользователя">
</form>
</body>
</html>
aktualizacjaUżytkownika.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Изменить данные пользователя</title>
</head>
<body>

Редактировать пользователя

<form action="/users/${param.id}" method="post">
    <input type="hidden" name = "id" value="${param.id}">
    <input type="text" name="name" value="${param.name}" placeholder=${param.name}>
    <input type="text" name="age" value="${param.age}" placeholder=${param.age}>
    <input type="hidden" name="_method" value="put">
    <input type="submit" value="Обновить">
</form>

</body>
</html>
Strona JSP (Java Server Page) zawiera dwa typy tekstu: statyczne dane źródłowe, które mogą być w jednym z formatów tekstowych (HTML, SVG, WML lub XML) oraz elementy JSP, które tworzą dynamiczną treść. Aby zrozumieć, czym jest JSP, pozwolę sobie skopiować i wkleić fragment bardzo dobrego artykułu jednego autora ( stąd ). „Zasadniczo przy pierwszym dostępie strona JSP jest przekształcana w serwlet i działa jako serwlet. Bardzo ważne jest, aby to zrozumieć. JSP NIE JEST stroną podobną do strony HTML — ważne jest, aby początkujący programista dobrze zrozumiał, że to to kolejny serwlet - po prostu nie trzeba programować jego wyjścia. Można go po prostu narysować. I podstawić dane w odpowiednich miejscach. Ale ponieważ strona JSP przynajmniej w jakiś sposób przypomina HTML, będzie to oczywiście łatwiejsze dla projektanta. I jeszcze raz ZDECYDOWANIE powtarzam początkującym - JSP to SERVLET . Jest on przygotowywany ze wszystkimi danymi na serwerze. To tutaj wstawiane są wszystkie dane. A użytkownik otrzymuje w przeglądarce gotową stronę HTML, która nie masz jakiekolwiek oznaki JAVA.” Możesz sam przekonać się, że strona JSP jest w rzeczywistości serwletem, ponieważ każda strona zawiera metodę, którą należy wykonać. Na przykład strona startowa Index.jsp stwierdza, że ​​po kliknięciu przycisku „Rozpocznij pracę z bazą danych” zostanie wykonana metoda method="get". Na stronie addUser.jsp, która odpowiada za utworzenie nowego użytkownika, po kliknięciu przycisku zapisu zostanie wykonana metoda method="post". Reszta strony JSP składa się ze zwykłych statycznych znaczników HTML, więc nie będziemy się nad nimi szczegółowo rozwodzić - jest to temat na osobny artykuł, którego jest wiele w Internecie. Stworzyliśmy więc naszą aplikację, pozostaje tylko przetestować ją w działaniu! Aby to zrobić, będziemy potrzebować wspomnianego powyżej kontenera serwletu Apache Tomcat. Kota można pobrać z oficjalnej strony (ja używam wersji 8). Następnie musimy stworzyć konfigurację w IDEA, aby uruchomić naszą aplikację poprzez Tomcat. Aby to zrobić, otwórz zakładkę „Edytuj konfiguracje”, Twoja pierwsza aplikacja korzystająca z serwletów Java — 4utwórz nową konfigurację Twoja pierwsza aplikacja korzystająca z serwletów Java - 5i wybierz Tomcat Server Local. W zakładce Serwer aplikacji określ ścieżkę do folderu, w którym znajduje się Tomcat, Twoja pierwsza aplikacja korzystająca z serwletów Java — 6a następnie przejdź do zakładki Wdrożenie. Ваше первое приложение с использованием Java-сервлетов - 7Tutaj konfigurujemy wdrożenie naszej aplikacji na serwerze lokalnym. Kliknij „+”, wybierz „Artefakt” -> Nazwa Twojego projektu: war (aplikację złożymy w plik wojny). Ваше первое приложение с использованием Java-сервлетов - 8To w zasadzie tyle! Na stronie „Serwer” możesz zobaczyć, że ta sama aplikacja będzie działać pod adresem „http://localhost:8080/”. Zapisz tę konfigurację i nadaj jej jakąś nazwę (moja nazwa konfiguracji to „Tommy”). Następnie w zakładce Maven w IDEA (po prawej stronie) użyjemy wtyczki war, aby wbudować nasz projekt w plik wojny (Wtyczki -> wojna -> wojna:war). Ваше первое приложение с использованием Java-сервлетов - 9Ваше первое приложение с использованием Java-сервлетов - 10Powodzenie! Strona startowa została uruchomiona. Teraz kliknij przycisk „Rozpocznij pracę z bazą danych”. Nasza strona JSP indeks.jsp wygeneruje żądanie GET, które zostanie przetworzone przez serwer. Serwer wygeneruje odpowiedź i zwróci ją nam w postaci listy wszystkich istniejących użytkowników (jeśli oczywiście znajdują się w bazie). I oto są! Ваше первое приложение с использованием Java-сервлетов - 12Spróbujmy usunąć jednego z użytkowników: Ваше первое приложение с использованием Java-сервлетов - 13To też działa! Napisaliśmy więc naszą pierwszą aplikację przy użyciu serwletów. Jak widać wszystko nie okazało się takie trudne :) W ramach pracy domowej możesz np. przywrócić do aplikacji funkcjonalność pracy z samochodami z poprzedniego artykułu. Te. utwórz osobny serwlet i strony jsp dla samochodów i naucz naszą aplikację wyświetlania listy samochodów użytkownika, dodawania do niego nowych samochodów, a także ich edycji i usuwania. Serwlety PS i JSP to dość stare technologie, a w Internecie często można znaleźć komentarze w duchu „po co te śmiecie?” Odpowiedź jest dość prosta – jest potrzebna przede wszystkim tym, którzy będą pracować nad prawdziwymi projektami, w których całkiem możliwe, że będzie pisanych przy ich pomocy sporo kodu. A przerabianie „starych rzeczy” na coś nowego, bez zrozumienia, jak to działa, nadal jest przyjemnością :) Aby dokładniej poznać temat JSP i serwletów, możesz skorzystać z książki „Head First Servlets and JSP” (w języku: Tylko angielski). Został napisany przez tych samych autorów, co słynny superbook „Head First Java”, który dla wielu może być gwarancją jakości :) Mam nadzieję, że ten artykuł był przydatny dla czytelników! Jeśli chcesz zobaczyć nowe artykuły, nie zapomnij wesprzeć autora w konkursie poprzez „polubienie go”. Albo jeszcze lepiej – „Bardzo mi się podoba” :) Dziękuję za uwagę i życzę powodzenia w nauce!
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION