JavaRush /Java Blog /Random-TW /您的第一個使用 Java servlet 的應用程式

您的第一個使用 Java servlet 的應用程式

在 Random-TW 群組發布
大家好!在本文中,您將熟悉 servlet 的基本 Web 開發概念,並能夠使用它們編寫簡單的應用程式。 為了避免不必要的步驟,我們不會從頭開始,並將繼續從我之前關於 Hibernate 的文章中您的第一個使用 Java servlet 的應用程式 - 1開發我們的應用程式。然而,由於我們剛開始使用 servlet,因此我從應用程式中刪除了與 Auto 類別相關的所有內容,只留下了 User 類別及其操作。專案結構將如下所示: 那麼,servlet!維基百科說:“Servlet 是一個 Java 接口,其實現擴展了伺服器的功能。Servlet 通過請求-響應原則與客戶端進行交互。” 確實如此。在這裡我們首先遇到「客戶端-伺服器應用程式架構」的概念。它的本質非常簡單,適合一張圖片(取自此處)。 您的第一個使用 Java servlet 的應用程式 - 2
您的第一個使用 Java Servlet 的應用程式 - 3
客戶端透過發送 HTTP 請求來聯繫伺服器。伺服器產生必要的資料(例如,從資料庫接收資料)並將其傳回給客戶端。最簡單的例子:在某個社群網路上,您按一下「好友」按鈕,從而向伺服器發送請求。伺服器檢查資料庫中您的好友清單並將其傳回給您(客戶端)。HTTP 請求的清單相當大,但如果您從未遇到過它們,那麼為了更好地理解它們,最好閱讀有關它們的信息,例如,這裡我們的任務是: 使用 servlet 建立 CRUD 應用程式。應用程式必須能夠使用處理 HTTP 請求的 servlet 在資料庫中建立、修改和刪除使用者。關於 Hibernate 的文章中的我們的應用程式已經知道如何執行此操作,但它是直接從 Java 程式碼控制的,更準確地說,是從 main() 方法控制的。這裡的請求將由客戶端(即您)發送:)我們需要做的第一件事是向 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>
我們新增了 3 個依賴項:
  1. javax.servlet-api 庫本身;
  2. JSTL 標籤庫。需要建立客戶端,即JSP頁面;
  3. Spring-WebMVC。我們需要一個 Spring 類,稍後我們將討論它。
servlet 的操作由servlet 容器管理。在我們的例子中,我們將使用 Apache Tomcat。這是一個相當流行的東西,您可能已經聽說過它了:) servlet 的生命週期由以下步驟組成:
  1. 如果容器中沒有servlet。
    • servlet 類別由容器載入。
    • 容器建立 servlet 類別的實例。
    • 容器呼叫 init() 方法。此方法會初始化 servlet,並在 servlet 可以為請求提供服務之前先呼叫方法。init() 方法在其整個生命週期中僅被呼叫一次。
  2. 服務客戶請求。每個請求都在其自己的單獨線程中處理。容器為每個請求呼叫 service() 方法。此方法判斷傳入請求的類型,並分發給該類型對應的方法來處理該請求。servlet 開發人員必須提供這些方法的實作。如果收到的請求未實作某個方法,則會呼叫父類別的方法,並且通常會向請求者傳回錯誤。
  3. 如果容器需要刪除 servlet,它會呼叫 destroy() 方法,該方法會從服務中刪除該 servlet。與 init() 方法一樣,此方法在整個 servlet 週期中也會被呼叫一次。
我們的 servlet 看起來非常簡單:
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");
    }
}
如您所看到的,它包含上面描述的 init() 方法,並實作了 4 個與四個 HTTP 請求一致的方法 - doGet()、doPost()、doPut() 和 doDelete()。它們分別允許我們接收、建立、編輯和刪除使用者。這些方法將 javax.servlet.http.HttpServletRequest 和 javax.servlet.http.HttpServletResponse 類別的輸入物件 - 即傳送到伺服器的請求和用戶端收到的回應。在方法內部,執行 UserService 類別的必要方法,為客戶端產生回應,然後重新導向至 /users 位址。例如,在 doGet() 方法中,我們取得所有使用者的清單。接下來,我們建立 RequestDispatcher 類別的對象,它允許我們在 Http 請求中包含對象,並將其重定向到特定資源(例如,客戶端 JSP 頁面)。在 doPut() 方法(更新用戶資料)中,我們處理 HTTP 請求,從中提取 id、name 和age 參數,找到指定 id 的用戶,並為其分配在請求,並返回頁面/users。然而,為了讓所有這些方法都能正常運作,我們需要設定 servlet。為此,我們使用 WEB-INF 資料夾中的 web.xml 檔案。
<?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>
原則上,該文件中的所有標籤都很直觀,但讓我們按順序瀏覽它們。<welcome-file-list> - 指定起始 JSP 頁面,該頁面將在應用程式啟動時首先開啟。在我們的例子中,這是index.jsp 頁面。<servlet> - 將我們的 UserSimpleServlet 類別註冊為 servlet。<servlet-mapping> 是一個非常重要的標籤。它定義將由 servlet 處理的 URL。在我們的例子中,這些都是 URL,因此我們只需指示“/”。但是,例如,如果我們有一個包含使用者及其電腦的應用程序,那麼我們可以建立第二個 servlet - SimpleAutoServlet。那麼使用者 servlet 的對應將是「/users」(即與處理使用者相關的請求),而對於 auto servlet 的對應將是「/autos」。最後,<過濾器>。它在內部定義了 org.springframework.web.filter.HiddenHttpMethodFilter 類別的物件。文章不涉及Spring,所以就不詳細講了。我只想說,它只是作為附加功能附加到我們的應用程式中。重點是我們將使用 JSP 頁面來建立客戶端。我們的資料將作為包含使用者清單的表格顯示在頁面上。在 JSP 頁面內,將使用 HTML <form/> 標籤。並且只能使用 HTTP GET 和 POST 請求從 <form/> 發送資料。也就是說,對於所有三個操作 - 更新、刪除和建立使用者 - 我們只能使用 POST 請求。我們無法使用 PUT 和 DELETE 請求。而且,原則上,這是非常正常且易於實現的,但 HiddenHttpMethodFilter 類別允許我們使用它們。這將使讀者更清楚應用程式中操作之間的差異。最後,讓我們轉向客戶端。它由五個 JSP 頁面表示。索引.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>
新增用戶.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="Name">
    <input required type="text" name="age" placeholder="Возраст">
    <input type="submit" value="Сохранить">
</form>
</body>
</html>
刪除用戶.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>
顯示用戶.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>Name</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>
更新用戶.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>
JSP 頁面(Java Server Page)包含兩種類型的文字:靜態來源數據,可以是其中一種文字格式(HTML、SVG、WML 或 XML),以及建構動態內容的 JSP 元素。為了理解 JSP 是什麼,我將允許自己複製並貼上一位作者的一篇非常好的文章(來自此處)。「本質上,JSP 在第一次被訪問時被轉換為 servlet,並作為 servlet 工作。理解這一點非常重要。JSP不是像HTML 頁面那樣的頁面- 對於新手程式設計師來說,清楚地理解這一點非常重要」是另一個servlet - 您只是不需要對其輸出進行程式設計。您可以簡單地繪製它。並在正確的位置替換資料。但是由於JSP 頁面至少在某種程度上類似於HTML,因此對於設計者來說顯然會更容易。我再次強烈告訴初學者 - JSP 是一個 SERVLET。它是用伺服器上的所有資料準備的。這是所有資料插入的地方。使用者在瀏覽器中收到現成的HTML 頁面,這並不需要任何數據。有沒有JAVA的跡象。” 你可以親眼看到,JSP頁面確實是一個servlet,因為每個頁面都包含一個需要執行的方法。例如,起始頁index.jsp 指出,當您按一下「開始使用資料庫」按鈕時,將執行method="get"。在負責建立新使用者的addUser.jsp頁面上,當您按一下儲存按鈕時,將執行method="post"。JSP 的其餘部分由普通的靜態 HTML 標記組成,因此我們不會詳細討論它們 - 這是另一篇文章的主題,Internet 上有很多這樣的文章。所以,我們已經創建了我們的應用程序,剩下的就是在行動中測試它!為此,我們需要上面提到的 Apache Tomcat servlet 容器。你可以從官網下載貓(我用的是8版)。接下來,我們需要在 IDEA 中建立配置以透過 Tomcat 運行我們的應用程式。為此,請開啟“編輯配置”選項卡, 您的第一個使用 Java Servlet 的應用程式 - 4建立新配置 您的第一個使用 Java servlet 的應用程式 - 5並選擇“Tomcat 伺服器本機”。在「應用程式伺服器」標籤中指定Tomcat所在資料夾的路徑, 您的第一個使用 Java Servlet 的應用程式 - 6然後進入「部署」標籤。 Ваше первое приложение с использованием Java-сервлетов - 7在這裡,我們在本地伺服器上配置應用程式的部署。點擊“+”,選擇“Artifact”->您的專案名稱:war(我們將把應用程式組裝成war檔)。 Ваше первое приложение с использованием Java-сервлетов - 8基本上就是這樣!在「伺服器」頁面上,您可以看到相同的應用程式將在「http://localhost:8080/」上運行。儲存此配置並為其命名(我的配置名稱是“Tommy”)。接下來,在 IDEA 的 Maven 標籤(右側)上,我們將使用 war 外掛程式將專案建置為 war 檔案(外掛程式 -> war -> war:war)。 Ваше первое приложение с использованием Java-сервлетов - 9Ваше первое приложение с использованием Java-сервлетов - 10成功!起始頁已啟動。現在點選「開始使用資料庫」按鈕。我們的 JSP 頁面 index.jsp 將產生 GET 請求,該請求將由伺服器處理。伺服器將產生回應並以所有現有使用者清單的形式傳回給我們(當然,如果它們在資料庫中)。他們就在這裡! Ваше первое приложение с использованием Java-сервлетов - 12讓我們嘗試刪除其中一個用戶: Ваше первое приложение с использованием Java-сервлетов - 13這也有效!因此,我們使用 servlet 編寫了第一個應用程式。正如您所看到的,一切都不是那麼困難:) 作為家庭作業,您可以將上一篇文章中使用汽車的功能返回到應用程式。那些。為汽車創建單獨的 servlet 和 jsp 頁面,並教導我們的應用程式顯示用戶汽車的清單、向他添加新車以及編輯和刪除它們。PS Servlet 和 JSP 是相當古老的技術,在網路上您經常可以找到「誰需要這個垃圾?」的評論。答案很簡單 - 它主要是那些將在實際專案中工作的人所需要的,在這些專案中很可能會有大量使用它們編寫的程式碼。在不了解其工作原理的情況下將“舊東西”切割成新東西仍然是一種樂趣:) 要更深入地研究 JSP 和 servlet 主題,您可以使用“Head First Servlets and JSP”一書(在僅限英語)。它與著名的超級書籍《Head First Java》是同一作者寫的,這對很多人來說可以是品質的保證:)我希望這篇文章對讀者有用!如果您想看到新文章,請不要忘記在比賽中透過「喜歡」他來支持作者。或更好 - “我非常喜歡它”:) 感謝您的關注,祝您學習順利!
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION