JavaRush /Blog Java /Random-VI /Tạo một ứng dụng web đơn giản sử dụng servlets và jsp (ph...
fatfaggy
Mức độ
Киев

Tạo một ứng dụng web đơn giản sử dụng servlets và jsp (phần 2)

Xuất bản trong nhóm
Tôi tiếp tục mô tả quá trình tạo một ứng dụng web bằng servlets, jsp, Maven và Tomcat. Bắt đầu bài viết , nếu cần thiết.
Chúng tôi tạo ra các thực thể.
Hãy tạo một lớp Người dùng trong gói thực thể, trong đó chúng ta sẽ tạo hai biến chuỗi riêng tư tên và mật khẩu. Hãy tạo các hàm tạo (mặc định và một hàm sẽ chấp nhận cả hai giá trị), getters/setters, ghi đè phương thức toString() để đề phòng, cũng như các phương thức Equals() và hashCode(). 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; } } Bây giờ chúng ta có thể bắt đầu tạo danh sách người dùng, nơi chúng ta sẽ thêm người dùng của mình và từ đó chúng ta sẽ đưa họ đi hiển thị. Nhưng có một vấn đề. Chúng tôi không tạo các đối tượng servlet của mình; Tomcat tạo chúng cho chúng tôi. Các phương thức mà chúng tôi ghi đè trong đó cũng đã được xác định cho chúng tôi và chúng tôi không thể thêm tham số. Làm thế nào chúng ta có thể tạo một danh sách chung có thể hiển thị trong cả hai servlet của chúng ta? Nếu chúng ta chỉ đơn giản tạo đối tượng danh sách của riêng mình trong mỗi servlet, thì chúng ta sẽ thêm người dùng vào một danh sách, nhưng việc hiển thị danh sách người dùng sử dụng servlet ListServlet sẽ hoàn toàn khác. Hóa ra là chúng ta cần một đối tượng chung cho cả hai servlet. Nói chung, chúng ta cần một đối tượng chung cho tất cả các lớp trong chương trình của chúng ta; đối tượng duy nhất cho toàn bộ chương trình. Tôi hy vọng bạn đã nghe điều gì đó về các mẫu thiết kế. Và có lẽ đối với một số người, đây là nhu cầu thực sự đầu tiên cần sử dụng mẫu Singleton trong chương trình của họ. Bạn có thể sáng tạo và tạo ra một số singleton thú vị, với việc kiểm tra và đồng bộ hóa hai lần (vâng, chúng tôi có ứng dụng đa luồng, vì Tomcat chạy các servlet trong các luồng khác nhau), nhưng tôi sẽ sử dụng tùy chọn khởi tạo sớm, vì trong trường hợp này nó khá phù hợp.
Tạo một mô hình.
Sau đó, chúng ta sẽ tạo một lớp (và triển khai mẫu singleton trong đó) trong gói mô hình và chúng ta cũng sẽ gọi nó một cách khá sặc sỡ là Model. Hãy tạo một đối tượng danh sách người dùng riêng tư trong đó và tạo hai phương thức: một để bạn có thể thêm người dùng và phương thức thứ hai - hãy để nó trả về một danh sách các chuỗi (tên người dùng). Vì đối tượng người dùng của chúng tôi bao gồm tên và mật khẩu nên chúng tôi không muốn “tiết lộ” mật khẩu người dùng, vì vậy chúng tôi sẽ chỉ trả về danh sách tên của họ. public class Model { private static Model instance = new Model(); private List model; public static Model getInstance() { return instance; } private Model() { model = new ArrayList<>(); } public void add(User user) { model.add(user); } public List list() { return model.stream() .map(User::getName) .collect(Collectors.toList()); } }
Một chút về mvc.
Vì bạn đã nghe nói về singleton, điều đó có nghĩa là bạn có thể đã nghe nói về một mẫu thiết kế khác - MVC (model-view-controller, hoặc trong model-view-controller của Nga, hoặc giống như trong model-view-controller của tiếng Anh). Bản chất của nó là tách logic nghiệp vụ khỏi cách trình bày. Tức là tách mã xác định việc cần làm khỏi mã xác định cách hiển thị . Chế độ xem (chế độ xem hoặc chỉ chế độ xem) chịu trách nhiệm về hình thức trình bày một số dữ liệu. Trong trường hợp của chúng tôi, lượt xem là các trang JSP của chúng tôi. Đó là lý do tại sao tôi đặt chúng vào một thư mục có tên là view. Mô hình là dữ liệu thực tế mà chương trình hoạt động. Trong trường hợp của chúng tôi, đây là những người dùng (danh sách người dùng). Vâng, bộ điều khiển là sợi dây kết nối giữa chúng. Họ lấy dữ liệu từ mô hình và chuyển nó sang các khung nhìn hoặc họ nhận một số dữ liệu từ Tomcat, xử lý và chuyển nó sang mô hình. Logic nghiệp vụ (nghĩa là phải làm gì ) phải được mô tả trong chúng chứ không phải trong mô hình hoặc trong dạng xem. Vì vậy, mọi người đều làm việc riêng của mình:
  • mô hình lưu trữ dữ liệu
  • Chế độ xem vẽ ra một cách trình bày đẹp mắt về dữ liệu
  • bộ điều khiển xử lý dữ liệu
Điều này cho phép tất cả chúng khá đơn giản và có thể bảo trì được. Và không phải là một đống khổng lồ tất cả mã trong một lớp. MVC không chỉ phù hợp với lập trình web mà nó còn rất phổ biến (nếu không phải luôn luôn) trong lĩnh vực này. Trong trường hợp của chúng tôi, servlet sẽ đóng vai trò là bộ điều khiển. Vâng, đây là một mô tả rất hời hợt và thậm chí thô sơ về mẫu này, nhưng bài viết này không phải về các mẫu thiết kế mà là về cách tạo một ứng dụng web đơn giản :) Ai muốn biết thêm - Google biết mọi thứ ! :) Hãy quay lại quan điểm của chúng tôi.
Tạo biểu mẫu để thêm người dùng.
Hãy thêm một biểu mẫu vào tệp add.jsp, bao gồm hai kiểu nhập văn bản (một kiểu thông thường, một kiểu nhập mật khẩu) và một nút để gửi dữ liệu đến máy chủ. Ở đây biểu mẫu có một thuộc tính phương thức với giá trị post. Điều này có nghĩa là dữ liệu từ biểu mẫu này sẽ được gửi đến máy chủ dưới dạng yêu cầu POST. Thuộc tính hành động không được chỉ định, có nghĩa là yêu cầu này sẽ được gửi đến cùng địa chỉ mà chúng tôi đã truy cập trang này (/add). Do đó, servlet của chúng tôi, được liên kết với địa chỉ này, khi nhận được yêu cầu GET, sẽ trả về jsp này cùng với biểu mẫu để thêm người dùng và nếu nó nhận được yêu cầu POST thì biểu mẫu này đã gửi dữ liệu của nó đến đó (chúng tôi sẽ truy xuất từ ​​​​đối tượng yêu cầu trong phương thức doPost(), xử lý nó và chuyển nó vào mô hình để lưu). Điều đáng lưu ý là ở đây đầu vào có tham số tên (đối với trường có tên, nó có tên giá trị và đối với trường có mật khẩu, nó có giá trị truyền). Đây là một điểm khá quan trọng. Vì để có được dữ liệu này (tên và mật khẩu sẽ được nhập) từ yêu cầu (đã có trong servlet), chúng tôi sẽ sử dụng chính xác tên và mật khẩu này. Nhưng nhiều hơn về điều này sau. Bản thân nút gửi dữ liệu một lần nữa được tạo ra ở dạng nút chứ không phải đầu vào, như thông lệ. Tôi không biết tùy chọn này phổ biến đến mức nào nhưng nó hoạt động với tôi trong Chrome :)
Xử lý yêu cầu POST bằng servlet.
Hãy quay lại servlet AddServlet. Chúng ta đã biết rằng để servlet của chúng ta có thể “bắt” các yêu cầu GET, chúng ta đã ghi đè phương thức doGet() từ lớp HttpServlet. Để hướng dẫn servlet của chúng tôi bắt các yêu cầu POST, chúng tôi cũng ghi đè phương thức doPost(). Nó nhận được các đối tượng yêu cầu và phản hồi tương tự từ Tomcat mà chúng ta sẽ làm việc cùng. Đầu tiên, hãy trích xuất từ ​​yêu cầu tên và truyền các tham số mà biểu mẫu đã gửi (nếu bạn đặt tên khác cho chúng trong biểu mẫu thì đó là tên bạn viết). Sau đó, chúng tôi sẽ tạo đối tượng người dùng bằng cách sử dụng dữ liệu nhận được. Sau đó chúng ta sẽ lấy đối tượng mô hình và thêm người dùng đã tạo vào mô hình. @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); }
Chuyển dữ liệu sang chế độ xem.
Bây giờ chúng ta hãy chuyển sang servlet ListServlet. Chúng ta đã triển khai phương thức doGet(), phương thức này chỉ đơn giản chuyển quyền điều khiển sang view list.jsp. Nếu bạn chưa có điều này, hãy thực hiện bằng cách tương tự với phương thức tương tự từ servlet AddServlet. Bây giờ, thật tuyệt nếu lấy danh sách tên người dùng từ mô hình và chuyển chúng đến chế độ xem, chế độ xem này sẽ nhận chúng ở đó và hiển thị chúng một cách đẹp mắt. Để làm điều này, chúng ta sẽ lại sử dụng đối tượng yêu cầu mà chúng ta đã nhận được từ Tomcat. Chúng ta có thể thêm một thuộc tính cho đối tượng này, đặt cho nó một số tên và trên thực tế, chính đối tượng mà chúng ta muốn chuyển sang dạng xem. Do thực tế là khi chuyển quá trình thực thi từ một servlet sang một khung nhìn, chúng ta chuyển đến đó cùng một đối tượng yêu cầu và phản hồi mà chính servlet đó đã nhận được, sau đó bằng cách thêm danh sách tên của chúng ta vào đối tượng yêu cầu, chúng ta có thể từ yêu cầu này đối tượng trong dạng xem tạo danh sách tên người dùng của chúng tôi và nhận. Chúng ta đã hoàn thành lớp ListServlet, vì vậy đây là mã cho toàn bộ lớp. 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 names = model.list(); req.setAttribute("userNames", names); RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/list.jsp"); requestDispatcher.forward(req, resp); } }
Thực thi mã java trong tệp jsp.
Bây giờ hãy chuyển sang tệp list.jsp. Tệp này sẽ chỉ được thực thi khi ListServlet vượt qua quá trình thực thi tại đây. Ngoài ra, trong servlet đó, chúng tôi đã chuẩn bị sẵn danh sách tên người dùng từ mô hình và chuyển nó vào đây trong đối tượng yêu cầu. Đưa ra một danh sách các tên, chúng ta có thể chạy vòng lặp for qua nó và in ra từng tên. Như tôi đã nói, các tệp jsp có thể thực thi mã java (về nguyên tắc, đây là điều khiến chúng khác với các trang html tĩnh). Để thực thi một số mã, chỉ cần đặt một công trình ở nơi chúng ta cần là đủ. <% // java code %> Bên trong một công trình như vậy, chúng ta có quyền truy cập vào một số biến: request - đối tượng yêu cầu của chúng ta, mà chúng ta đã truyền từ servlet, nơi nó được gọi đơn giản req reply - đối tượng phản hồi, trong The servlet được gọi là resp out - một đối tượng thuộc loại JspWriter (được kế thừa từ Writer thông thường), với sự trợ giúp của nó, chúng ta có thể “viết” nội dung nào đó trực tiếp vào chính trang html. Out.println("Xin chào thế giới!") rất giống với System.out.println("Xin chào thế giới!"), Nhưng đừng nhầm lẫn chúng! out.println() "ghi" vào trang html và System.out.println - vào đầu ra của hệ thống. Nếu bạn gọi phương thức System.out.println() bên trong phần có mã jsp, bạn sẽ thấy kết quả trong bảng điều khiển Tomcat chứ không phải trên trang như bạn muốn :) Bạn có thể tìm kiếm các đối tượng có sẵn khác bên trong jsp đây . Sử dụng đối tượng yêu cầu, chúng ta có thể lấy danh sách các tên được truyền từ servlet (chúng ta đã đính kèm thuộc tính tương ứng vào đối tượng này) và sử dụng đối tượng out, chúng ta có thể hiển thị các tên này. Bây giờ chúng ta hãy thực hiện việc này một cách đơn giản dưới dạng danh sách html: Nếu chúng ta chỉ muốn hiển thị danh sách khi có người dùng và nếu không thì hiển thị cảnh báo rằng chưa có người dùng nào, chúng ta có thể viết lại phần này một chút: Bây giờ chúng ta biết cách chuyển dữ liệu từ servlet sang chế độ xem - chúng tôi có thể cải thiện AddServlet của mình một chút để hiển thị thông báo về việc thêm người dùng thành công. Để thực hiện điều này, trong phương thức doPost(), sau khi thêm người dùng mới vào mô hình, chúng ta có thể thêm tên của người dùng này vào các thuộc tính của đối tượng req và chuyển điều khiển trở lại chế độ xem add.jsp. Và trong đó đã tạo một phần có mã Java, nơi bạn có thể kiểm tra xem thuộc tính đó có trong yêu cầu hay không và nếu có thì sẽ hiển thị thông báo rằng người dùng đã được thêm thành công. Sau những thay đổi này, mã hoàn chỉnh của servlet AddServlet sẽ trông giống như thế này: Ở đây, ở cuối phương thức doPost(), chúng ta đặt một thuộc tính có tên của người dùng đã thêm vào mô hình và sau đó gọi doGet( ) mà chúng tôi chuyển yêu cầu và phản hồi hiện tại. Và phương thức doGet() đã chuyển quyền điều khiển sang dạng xem, nơi nó gửi một đối tượng yêu cầu có tên của người dùng được thêm vào được đính kèm dưới dạng thuộc tính. Cần phải sửa chính add.jsp để nó hiển thị thông báo như vậy nếu có thuộc tính đó. Add.jsp cuối cùng
    <% List names = (List ) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { for (String s : names) { out.println("
  • " + s + "
  • "); } } %>
<% List names = (List ) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { out.println(" "); for (String s : names) { out.println("
  • " + s + "
  • "); } out.println("
    "); } else out.println("

    There are no users yet!

    "); %>
    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); } } <%@ page contentType="text/html;charset=UTF-8" language="java" %> Add new user

    Super app!

    <% if (request.getAttribute("userName") != null) { out.println("

    User '" + request.getAttribute("userName") + "' added!

    "); } %>

    Add user

    Phần thân của trang bao gồm một div có tiêu đề, theo sau là vùng chứa div cho nội dung, kiểm tra xem thuộc tính có tên người dùng có tồn tại trong đó hay không, sau đó là div có biểu mẫu để thêm người dùng và ở cuối chân trang có một nút để quay lại trang chính. Có vẻ như có quá nhiều div, nhưng chúng ta sẽ sử dụng chúng sau khi thêm kiểu :) Chà, phiên bản cuối cùng là list.jsp. Vì vậy , chúng ta có một ứng dụng web hoạt động hoàn chỉnh có thể lưu trữ và thêm người dùng. như hiển thị một danh sách tên của họ. Tất cả những gì còn lại là tô điểm cho nó... :) <%@ page import="java.util.List" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> Users

    Super app!

    Users

    <% List names = (List ) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { out.println(" "); for (String s : names) { out.println("
  • " + s + "
  • "); } out.println("
    "); } else out.println("

    There are no users yet!

    "); %>
    Thêm phong cách. Chúng tôi sử dụng khung W3.CSS.
    Hiện tại, ứng dụng của chúng tôi đang hoạt động, nhưng thực sự điên rồ :) Chúng tôi cần thêm nền, màu sắc cho văn bản và nút, tạo kiểu cho danh sách, căn chỉnh, thêm thụt lề, nói chung là rất nhiều thứ. Nếu bạn viết kiểu thủ công, có thể mất rất nhiều thời gian và công sức. Vì vậy, tôi khuyên bạn nên sử dụng CSS framework W3.CSS . Nó đã có sẵn các lớp với các kiểu; tất cả những gì còn lại là đặt vào đúng vị trí các lớp CSS mà chúng ta muốn áp dụng ở những nơi này. Để thêm chúng vào các trang của chúng tôi, trước tiên chúng tôi cần đưa vào một tệp có kiểu. Điều này có thể được thực hiện theo hai cách: 1. xem qua các trang của chúng tôi và chèn một liên kết trực tiếp đến tệp có kiểu trong phần đầu. Tùy chọn này phù hợp nếu bạn có kết nối Internet liên tục. Sau đó, khi bạn mở các trang của mình trên máy chủ cục bộ, các kiểu sẽ được lấy từ Internet. 2. Nếu bạn muốn có tất cả các kiểu cục bộ và không phụ thuộc vào kết nối Internet, bạn chỉ cần tải xuống tệp có kiểu và đặt nó ở đâu đó bên trong thư mục web (ví dụ: web/styles/w3.css), sau đó xem qua tất cả các trang của chúng tôi (index.html, add.jsp, list.jsp) và nhập liên kết đến tệp này với các kiểu bên trong phần đầu. Sau đó, chỉ cần xem qua các thẻ và gắn thẻ chúng với các kiểu mà bạn thích . Tôi sẽ không đi sâu vào vấn đề này một cách chi tiết mà sẽ ngay lập tức đưa ra các phiên bản làm sẵn của ba tệp của tôi với các lớp kiểu được sắp xếp. index.html add.jsp list.jsp Thế thôi :) Nếu bạn vẫn còn thắc mắc hoặc có bất kỳ nhận xét nào, hoặc ngược lại, có gì đó không ổn - hãy để lại nhận xét. Chà, tôi sẽ đính kèm một vài ảnh chụp màn hình về những gì đã xảy ra. Và cuối cùng. Nếu bạn muốn thực hành với dự án này, bạn có thể thử: Super app!

    Super app!

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

    Super app!

    <% if (request.getAttribute("userName") != null) { out.println("
    \n" + " ×\n" + "
    User '" + request.getAttribute("userName") + "' added!
    \n" + "
    "); } %>

    Add user

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

    Super app!

    Users

    <% List names = (List ) request.getAttribute("userNames"); if (names != null && !names.isEmpty()) { out.println("
      "); for (String s : names) { out.println("
    • " + s + "
    • "); } out.println("
    "); } else out.println("
    \n" + " ×\n" + "
    There are no users yet!
    \n" + "
    "); %>
    Trang chủ ứng dụng Thêm cửa sổ người dùng danh sách người dùng
    • tạo một servlet và jsp để xóa một người dùng và một vài thứ khác để thay đổi/chỉnh sửa người dùng hiện có. Bạn sẽ nhận được một ứng dụng web CrUD thực sự :) trên servlets))
    • danh sách thay thế (Danh sách ) để làm việc với cơ sở dữ liệu để người dùng đã thêm không biến mất sau khi máy chủ được khởi động lại :)
    Chúc may mắn!
    Bình luận
    TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
    GO TO FULL VERSION