添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

創建實體

entities 包中,我們將創建一個 User 具有兩個私有字符串變量的類: name password 。創建構造函數(默認構造函數和接受兩個值的構造函數)和 getter/setter,並重寫 toString() 方法以防萬一,以及 equals() 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; 現在我們可以開始創建用戶列表了。我們將向其中添加用戶,並從中獲取用戶以顯示它們。但是,我們確實有一個問題。我們不創建我們的 servlet 對象。 Tomcat 為我們做了這件事。我們在其中重寫的方法已經為我們定義好了,我們不能傳參。那麼我們如何創建一個在我們的兩個 servlet 中都可見的共享列表呢?如果我們只是在每個 servlet 中創建一個列表對象,那麼我們會將用戶添加到一個列表中,但會在 ListServlet 中顯示另一個列表中的 用戶 . 所以我們需要一個由兩個 servlet 共享的對象。一般來說,我們需要一個由我們程序中的所有類共享的對象:一個對像用於整個程序。我希望你聽說過一些關於設計模式的事情。對於某些人來說,這可能是他們程序中第一次真正需要 單例 模式。您可以瘋狂地製作一些帶有雙重檢查和同步的甜蜜 單例(是的,我們的應用程序是多線程的,因為 Tomcat servlet 在單獨的線程上運行)。 但我將使用早期初始化技術,因為它完全可以滿足我們的目的。

創建模型

在模型 包中創建一個類(並實現 單例 模式)並將其命名為不尋常的東西。例如, 模型 。我們將在我們的類中創建一個私有用戶列表,並實現兩個方法:一個添加用戶,另一個返回字符串列表(用戶名)。由於我們的用戶對象包含用戶名和密碼,並且我們不想洩露用戶密碼,因此我們只有一個名稱列表。 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)。其目的是將業務邏輯與視圖分開。也就是說,將決定做什麼的代碼與決定如何顯示東西的代碼分開。視圖負責數據的呈現方式 在我們的例子中,視圖是我們的 JSP 頁面 。這正是我將它們放在名為 views 的文件夾中的原因。 模型 是程序實際使用的數據。在我們的例子中,這是用戶(用戶列表)。而控制器是它們之間的紐帶。他們從模型中獲取數據並將其傳遞給視圖(或者從 Tomcat中獲取一些數據 ,對其進行處理,並將其傳遞給模型)。您在其中定義您的業務邏輯(程序應該做什麼),而不是在模型或視圖中。因此,每個部分處理自己的業務:
  • 模型存儲數據;
  • 視圖呈現數據的漂亮表示;
  • 控制器處理數據處理。
  • 這允許程序非常簡單和可維護,而不是一個類中所有代碼的巨大堆。 MVC 不僅適用於 Web 編程,而且在該領域中使用得特別頻繁(幾乎總是如此)。在我們的例子中,servlet 將充當控制器。這是對模式的非常膚淺和簡短的描述,但 MVC 不是本文的主題。如果有人想了解更多,谷歌是你的朋友! 創建用於添加用戶的表單。 將表單添加到 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> 這裡的表單有一個 method 屬性,其值為 post 這表示此表單中的數據將作為POST 請求 發送到服務器。未指定action屬性,這意味著請求將發送到我們訪問此頁面的相同地址 ( / add )。因此,在收到 GET 請求 後,綁定到該地址的 servlet 會返回帶有添加用戶表單的 JSP 。 如果它收到一個 POST 請求 ,那麼我們就知道表單在這裡發送了它的數據(我們從 doPost() 方法、過程,並傳遞給模型進行保存)。值得注意的是,輸入字段有一個名為 name 的參數(用於用戶名,或 pass 用於密碼)。這是非常重要的一點。因此,要從請求(在 servlet 內)接收此數據(將輸入的用戶名和密碼),我們將使用這些 名稱 傳遞 字段。但稍後會詳細介紹。我用於發送數據的按鈕再次被製作為按鈕 而不是通常的輸出字段。我不知道這種方法的採用有多廣泛,但它適用於我(Chrome 瀏覽器)。

    POST 請求的 Servlet 處理

    讓我們回到 AddServlet 。我提醒您,為了讓我們的 servlet 能夠“捕獲” GET 請求 ,我們覆蓋了 HttpServlet doGet() 類中的方法。為了讓我們的 servlet 也能捕獲 POST 請求 ,我們還必須覆蓋該方法。 Tomcat 向它傳遞我們將使用的類似請求和響應對象。首先,提取請求的名稱並傳遞表單發送的參數(如果您在表單中指定了不同的名稱,則使用這些名稱)。之後,使用接收到的數據創建一個用戶對象。然後我們獲取模型對象並將創建的用戶添加到模型中。 doPost() @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 收到的請求對象。我們可以給這個對象添加一個屬性,給它起一個名字。其實我們可以把我們要傳遞的對象添加到視圖 . 由於在將控制從 servlet 轉移到視圖時,我們向視圖傳遞了與 servlet 接收到的相同的請求和響應對象,因此我們可以將名稱列表添加到請求對象,然後從請求中獲取用戶名列表視圖中的對象。我們已經完成了 ListServlet 類,所以我將在這裡展示整個類的代碼: 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);

    在 JSP 文件中運行 Java 代碼

    是時候查看 list.jsp 了。它只會在 ListServlet 將控制權轉移給它時執行。此外,我們已經從 servlet 中的模型準備了用戶名列表,並將其傳遞到請求對像中。由於我們有姓名列表,我們可以使用循環對其進行迭代 for 並顯示每個姓名。正如我之前所說, JSP 文件 可以執行 Java 代碼 (這就是它們與靜態 HTML 頁面的不同之處)。要執行一些代碼,我們需要做的就是將以下結構放在適當的位置: <!-- html code --> // Java code <!-- html code --> 在這個結構中,我們可以訪問幾個變量:
  • request — 我們的請求對象,我們從 servlet 傳遞過來的,它被簡稱為 req
  • response — 響應對象(在 servlet 中稱為 resp );
  • out — 一個 JspWriter 對象(它繼承了一個普通的 Writer ),我們可以使用它來將某些內容直接“寫入”到 HTML 頁面 本身。語句 out.println("Hello, World!")與 System.out.println("Hello, World!") 非常相似,但不要混淆它們!
  • out.println() “寫入”到 HTML 頁面 ,而 System.out.println 寫入 系統輸出流 。如果您使用 Java 代碼 JSP 部分中調用 System.out.println() ,您將在 Tomcat 控制台中看到結果,而不是在頁面上。
  • 您可以在此處 查找 JSP 中可用的其他對象。我們可以使用 request 對象獲取從 servlet 傳遞的名稱列表(我們將相應的屬性附加到該對象),然後使用 out 對象 顯示這些名稱。讓我們顯示它們(暫時,作為一個簡單的 HTML 列表): List<String> names = (List<String>) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { for (String s : names) { out.println("<li>" + s + "</li>"); 如果我們只需要在有用戶時顯示列表,否則顯示沒有用戶的警告,那麼我們可以稍微改寫這部分: 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>"); 現在我們知道如何將數據從 servlet 傳遞到視圖,我們可以改進我們的 AddServlet 以便它顯示有關成功添加用戶的通知。為此,在 doPost() 方法中,在將新用戶添加到模型後,我們可以將此用戶名添加到 req 對象的屬性並將控制權傳回視圖 ( add.jsp ) 。現在我們將向其中添加一個帶有 Java 代碼的部分,我們將在其中檢查請求是否具有這樣的屬性,如果有,那麼我們將顯示一條消息,表明用戶已成功添加。完成這些更改後, 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 ,以便在沒有此類屬性時顯示通知。 這是add.jsp 的最終版本: <%@ page contentType="text/html;charset=UTF-8" language="java" %> <title>Add new user</title> </head> <h1>Super app!</h1> if (request.getAttribute("userName") != null) { out.println("<p>User '" + request.getAttribute("userName") + "' added!</p>"); <h2>Add user</h2> <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> <button onclick="location.href='/'">Back to main</button> </body> </html> 頁面主體由以下部分組成:
  • 帶有標題的 div;
  • 內容的 div 容器,其中包括檢查是否存在具有用戶名的屬性;
  • 帶有添加用戶表單的 div;
  • 在底部,一個帶有返回主頁按鈕的頁腳。
  • 這可能看起來像太多的 div,但我們稍後會在添加樣式時使用它們。 這是list.jsp 的最終版本: <%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <title>Users</title> </head> <h1>Super app!</h1> <h2>Users</h2> 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>"); <button onclick="location.href='/'">Back to main</button> </body> </html> 因此,我們有一個可以保存和添加用戶並顯示他們姓名列表的完整工作的 Web 應用程序。現在我們只需要讓它漂亮...... :) 使用 servlet 和 JSP 創建簡單的 Web 應用程序(第 2 部分)- 2

    添加樣式。我們將使用 W3.CSS 框架

    目前,我們的應用程序可以運行,但它看起來絕對離譜。因此,讓我們添加背景、為文本和按鈕著色、為列表添加樣式、對齊元素、添加縮進等等。手動編寫樣式會花費大量時間並耗費我們的精力。所以我建議使用 W3.CSS 框架。它已經有帶有樣式的現成類。我們只需要將要使用的 CSS 類安排在正確的位置即可。要將它們添加到我們的頁面,我們首先連接樣式文件。有兩種方法可以做到這一點:

    瀏覽我們的頁面並在標題部分插入以下樣式文件的直接鏈接

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

    如果您有永久的 Internet 連接,則此選項適用。當您在本地服務器上打開您的頁面時,樣式將從 Internet 中提取。

    但是如果你想在本地擁有所有樣式而不依賴於 Internet 連接,請下載樣式文件並將其放在 web 文件 夾中的某個位置(例如 web/styles/w3.css )。然後瀏覽我們所有的頁面( index.html、add.jsp、list.jsp )並將以下鏈接添加到 head 部分內的樣式文件:

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

    之後,只需瀏覽標籤並添加您喜歡的樣式即可。這個我就不詳細說了。相反,我將只提供三個帶有光柵樣式類的文件的即用型版本。

    索引.html <!DOCTYPE html> <html lang="en"> <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 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> </body> </html> 添加.jsp <%@ page contentType="text/html;charset=UTF-8" language="java" %> <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 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> <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 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> </body> </html> 列表.jsp <%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <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 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> 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 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> </body> </html> 就是這樣。:) 如果您還有任何問題或意見,或者有什麼不對,請發表評論。我將附上幾張截圖,說明結果如何。 最後 ,如果你想練習這個項目,你可以嘗試以下方法:
  • 製作一個 servlet 和 JSP 來刪除用戶,並添加另一對來編輯現有用戶。結果將是使用 servlet 構建的真正的 CRUD Web 應用程序。;)
  • 將List替換為數據庫,這樣添加的用戶不會在服務器重啟後消失。:)
  • 祝你好運! CodeGym 是幫助您從零開始學習 Java 程式設計的線上課程。這個課程是讓初學者成為 Java 大師的完美途徑。內容有 1200+ 個任務,並為您即時驗證,還提供 Java 基礎理論中不可不知的內容。為了讓你在學習上取得成功,我們實作了一系列激勵性功能,像是小測驗、編碼專案,還有關於高效學習以及 Java 開發人員職涯的內容。