JavaRush /Blog Java /Random-VI /Ứng dụng đầu tiên của bạn sử dụng Java servlet

Ứng dụng đầu tiên của bạn sử dụng Java servlet

Xuất bản trong nhóm
Chào mọi người! Trong bài viết này, bạn sẽ làm quen với khái niệm phát triển web cơ bản về servlet và có thể viết một ứng dụng đơn giản bằng cách sử dụng chúng. Ứng dụng đầu tiên của bạn sử dụng Java servlet - 1Để tránh các bước không cần thiết, chúng tôi sẽ không bắt đầu lại từ đầu và sẽ tiếp tục làm việc trên ứng dụng của mình từ bài viết trước của tôi về Hibernate . Tuy nhiên, vì chúng ta mới bắt đầu với servlet nên tôi đã xóa mọi thứ liên quan đến lớp Auto khỏi ứng dụng và chỉ để lại lớp User cũng như các hành động của nó. Cấu trúc dự án sẽ như thế này: Ứng dụng đầu tiên của bạn sử dụng Java servlet - 2Vì vậy, servlet! Wikipedia nói: "Servlet là một giao diện Java có khả năng triển khai mở rộng chức năng của máy chủ. Một servlet tương tác với các máy khách thông qua nguyên tắc đáp ứng yêu cầu." Và thực sự là như vậy. Ở đây lần đầu tiên chúng ta bắt gặp khái niệm “kiến trúc ứng dụng máy khách-máy chủ”. Bản chất của nó khá đơn giản và nằm gọn trong một bức tranh (lấy từ đây ).
Ứng dụng đầu tiên của bạn sử dụng Java Servlets - 3
Máy khách liên hệ với máy chủ bằng cách gửi yêu cầu HTTP. Máy chủ tạo dữ liệu cần thiết (ví dụ: nhận dữ liệu từ cơ sở dữ liệu) và trả lại cho máy khách. Ví dụ đơn giản nhất: trên một mạng xã hội nhất định, bạn nhấp vào nút “Bạn bè” và do đó gửi yêu cầu đến máy chủ. Máy chủ kiểm tra danh sách bạn bè của bạn trong cơ sở dữ liệu và trả lại cho bạn (máy khách). Danh sách các yêu cầu HTTP khá lớn, nhưng nếu bạn chưa bao giờ gặp chúng, thì để hiểu rõ hơn, tốt hơn hết bạn nên đọc về chúng, chẳng hạn như tại đây . Nhiệm vụ của chúng ta là: Tạo một ứng dụng CRUD sử dụng servlet. Ứng dụng phải có khả năng tạo, sửa đổi và xóa người dùng khỏi cơ sở dữ liệu bằng cách sử dụng một servlet xử lý các yêu cầu HTTP. Ứng dụng của chúng ta từ bài viết về Hibernate đã biết cách thực hiện việc này, nhưng nó được điều khiển trực tiếp từ mã Java, chính xác hơn là từ phương thức main(). Ở đây các yêu cầu sẽ được gửi bởi khách hàng, tức là bạn :) Điều đầu tiên chúng ta cần làm là thêm các phụ thuộc mới vào tệp pom.xml của mình
<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>
Chúng tôi đã thêm 3 phụ thuộc:
  1. Bản thân thư viện javax.servlet-api;
  2. Thư viện thẻ JSTL. Sẽ cần thiết để tạo phía máy khách, cụ thể là các trang JSP;
  3. Spring-WebMVC. Chúng ta sẽ cần một lớp Spring mà chúng ta sẽ nói đến sau.
Hoạt động của servlet được quản lý bởi servlet container. Trong trường hợp của chúng tôi, chúng tôi sẽ sử dụng Apache Tomcat. Một điều khá phổ biến và có thể bạn đã từng nghe về nó :) Vòng đời của một servlet bao gồm các bước sau:
  1. Nếu không có servlet trong container.
    • Lớp servlet được tải bởi container.
    • Vùng chứa tạo một thể hiện của lớp servlet.
    • Vùng chứa gọi phương thức init(). Phương thức này khởi tạo servlet và được gọi đầu tiên trước khi servlet có thể phục vụ các yêu cầu. Phương thức init() chỉ được gọi một lần trong toàn bộ vòng đời của nó.
  2. Phục vụ một yêu cầu của khách hàng. Mỗi yêu cầu được xử lý trong luồng riêng biệt. Vùng chứa gọi phương thức service() cho mỗi yêu cầu. Phương thức này xác định loại yêu cầu đến và phân phối nó đến phương thức tương ứng với loại này để xử lý yêu cầu. Nhà phát triển servlet phải cung cấp các triển khai cho các phương thức này. Nếu nhận được yêu cầu mà phương thức không được triển khai, phương thức của lớp cha sẽ được gọi và thường kết thúc bằng lỗi được trả về cho người yêu cầu.
  3. Trong trường hợp container cần xóa một servlet, nó gọi phương thức destroy() để loại bỏ servlet đó khỏi dịch vụ. Giống như phương thức init(), phương thức này cũng được gọi một lần trong toàn bộ chu trình servlet.
servlet của chúng tôi sẽ trông khá đơn giản:
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");
    }
}
Như bạn có thể thấy, nó chứa phương thức init(), được mô tả ở trên và triển khai 4 phương thức trùng với bốn yêu cầu HTTP - doGet(), doPost(), doPut() và doDelete(). Mỗi người trong số họ sẽ cho phép chúng tôi lần lượt nhận, tạo, chỉnh sửa và xóa người dùng. Các phương thức này lấy làm đối tượng đầu vào của các lớp javax.servlet.http.HttpServletRequest và javax.servlet.http.HttpServletResponse - nghĩa là yêu cầu được gửi đến máy chủ và phản hồi mà máy khách nhận được. Bên trong các phương thức, các phương thức cần thiết của lớp UserService được thực thi, một phản hồi được tạo cho máy khách và sau đó được chuyển hướng đến địa chỉ /users. Ví dụ: trong phương thức doGet() chúng ta nhận được danh sách tất cả người dùng. Tiếp theo, chúng ta tạo một đối tượng của lớpRequestDispatcher, cho phép chúng ta đưa các đối tượng vào một yêu cầu Http, cũng như chuyển hướng nó đến một tài nguyên cụ thể (ví dụ: trang JSP máy khách). Trong phương thức doPut() (cập nhật dữ liệu người dùng), chúng tôi xử lý yêu cầu HTTP, trích xuất các tham số id, tên và tuổi từ nó, tìm người dùng có id được chỉ định, gán cho anh ta tên và tuổi đi kèm với anh ta trong yêu cầu và quay lại trang /users. Tuy nhiên, để tất cả các phương thức này hoạt động chính xác, chúng ta cần cấu hình servlet. Để làm điều này, chúng tôi sử dụng tệp web.xml trong thư mục 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>
Về nguyên tắc, tất cả các thẻ trong tệp này đều trực quan, nhưng chúng ta hãy xem xét chúng một cách tuần tự. <welcome-file-list> - trang JSP bắt đầu được chỉ định, trang này sẽ được mở đầu tiên khi ứng dụng được khởi chạy. Trong trường hợp của chúng tôi, đây là trang index.jsp. <servlet> - đăng ký lớp UserSimpleServlet của chúng tôi làm servlet. <servlet-mapping> là một thẻ rất quan trọng. Nó xác định các URL sẽ được servlet xử lý. Trong trường hợp của chúng tôi, đây đều là các URL, vì vậy chúng tôi chỉ cần chỉ ra “/”. Tuy nhiên, ví dụ: nếu chúng ta có một ứng dụng với người dùng và máy của họ, thì chúng ta có thể tạo một servlet thứ hai - SimpleAutoServlet. Sau đó, ánh xạ cho servlet người dùng sẽ là “/users” (nghĩa là các yêu cầu liên quan đến việc xử lý người dùng) và đối với servlet tự động, nó sẽ là “/autos”. Và cuối cùng, <bộ lọc>. Nó định nghĩa bên trong một đối tượng của lớp org.springframework.web.filter.HiddenHttpMethodFilter. Bài viết không liên quan đến Spring nên tôi sẽ không nói chi tiết về nó. Hãy để tôi nói rằng nó chỉ được đính kèm vào ứng dụng của chúng tôi như một tính năng bổ sung. Vấn đề là chúng ta sẽ sử dụng các trang JSP để tạo phía máy khách. Dữ liệu của chúng tôi sẽ được hiển thị trên trang dưới dạng bảng có danh sách người dùng. Bên trong các trang JSP, các thẻ HTML <form/> sẽ được sử dụng. Và chỉ có thể sử dụng các yêu cầu HTTP GET và POST để gửi dữ liệu từ <form/>. Nghĩa là, đối với cả ba thao tác - cập nhật, xóa và tạo người dùng - chúng ta sẽ chỉ phải sử dụng các yêu cầu POST. Chúng tôi sẽ không thể sử dụng các yêu cầu PUT và DELETE. Và về nguyên tắc, điều này khá bình thường và dễ thực hiện, nhưng lớp HiddenHttpMethodFilter cho phép chúng ta sử dụng chúng. Điều này sẽ giúp người đọc hiểu rõ hơn sự khác biệt giữa các thao tác trong ứng dụng. Cuối cùng, hãy chuyển sang phía khách hàng. Nó được đại diện bởi năm trang JSP. chỉ mục.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>
addUser.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>
xóaUser.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>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>
cập nhậtUser.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>
Trang JSP (Trang máy chủ Java) chứa hai loại văn bản: dữ liệu nguồn tĩnh, có thể ở một trong các định dạng văn bản (HTML, SVG, WML hoặc XML) và các phần tử JSP, xây dựng nội dung động. Để hiểu JSP là gì, tôi sẽ cho phép mình sao chép và dán một đoạn bài viết rất hay của một tác giả ( từ đây ). "Về cơ bản, JSP được chuyển đổi thành một servlet trong lần đầu tiên nó được truy cập và hoạt động như một servlet. Điều này rất quan trọng để hiểu. JSP KHÔNG phải là một trang giống như một trang HTML - điều quan trọng là một lập trình viên mới làm quen phải hiểu rõ ràng rằng điều này là một servlet khác - bạn không cần phải lập trình đầu ra của nó. Bạn có thể chỉ cần vẽ nó. Và thay thế dữ liệu vào đúng vị trí. Nhưng vì trang JSP ít nhất giống với HTML ở một khía cạnh nào đó, nên rõ ràng là nó sẽ dễ dàng hơn cho người thiết kế. Và tôi một lần nữa MẠNH MẼ nói với những người mới bắt đầu - JSP là một SERVLET . Nó được chuẩn bị với tất cả dữ liệu trên máy chủ. Đây là nơi tất cả dữ liệu được chèn vào. Và người dùng sẽ nhận được một trang HTML tạo sẵn trong trình duyệt, trang này không có có bất kỳ dấu hiệu nào của JAVA." Bạn có thể tự mình thấy rằng trang JSP thực sự là một servlet, vì mỗi trang chứa một phương thức cần được thực thi. Ví dụ: trang bắt đầu index.jsp cho biết rằng khi bạn nhấp vào nút "Bắt đầu làm việc với cơ sở dữ liệu", phương thức = "get" sẽ được thực thi. Trên trang addUser.jsp, trang chịu trách nhiệm tạo người dùng mới, khi bạn nhấp vào nút lưu, phương thức = "post" sẽ được thực thi. Phần còn lại của JSP bao gồm các đánh dấu HTML tĩnh thông thường, vì vậy chúng tôi sẽ không đề cập chi tiết đến chúng - đây là chủ đề của một bài viết riêng, trong đó có rất nhiều bài viết trên Internet. Vì vậy, chúng tôi đã tạo ứng dụng của mình, tất cả những gì còn lại là thử nghiệm nó trong thực tế! Để làm điều này, chúng ta sẽ cần bộ chứa servlet Apache Tomcat được đề cập ở trên. Bạn có thể tải xuống con mèo từ trang web chính thức (tôi sử dụng phiên bản 8). Tiếp theo, chúng ta cần tạo cấu hình trong IDEA để chạy ứng dụng của mình thông qua Tomcat. Để thực hiện việc này, hãy mở tab "Chỉnh sửa cấu hình", Ứng dụng đầu tiên của bạn sử dụng Java Servlets - 4tạo cấu hình mới Ứng dụng đầu tiên của bạn sử dụng Java servlet - 5và chọn Máy chủ Tomcat cục bộ. Trong tab Máy chủ ứng dụng, chỉ định đường dẫn đến thư mục chứa Tomcat. Ứng dụng đầu tiên của bạn sử dụng Java Servlets - 6Tiếp theo, chuyển đến tab Triển khai. Ваше первое приложение с использованием Java-сервлетов - 7Ở đây chúng tôi định cấu hình triển khai ứng dụng của mình trên máy chủ cục bộ. Nhấp vào "+", chọn "Artifact" -> Tên dự án của bạn: war (chúng tôi sẽ tập hợp ứng dụng thành một tệp chiến tranh). Ваше первое приложение с использованием Java-сервлетов - 8Về cơ bản là vậy! Trên trang "Máy chủ", bạn có thể thấy rằng ứng dụng tương tự sẽ chạy tại "http://localhost:8080/". Lưu cấu hình này và đặt tên gì đó (tên cấu hình của tôi là “Tommy”). Tiếp theo, trên tab Maven trong IDEA (ở bên phải), chúng ta sẽ sử dụng war plugin để xây dựng dự án của mình thành một tệp war (Plugins -> war -> war:war). Ваше первое приложение с использованием Java-сервлетов - 9Ваше первое приложение с использованием Java-сервлетов - 10Thành công! Trang bắt đầu đã ra mắt. Bây giờ hãy nhấp vào nút “Bắt đầu làm việc với cơ sở dữ liệu”. Trang JSP của chúng tôi index.jsp sẽ tạo ra một yêu cầu GET được máy chủ xử lý. Máy chủ sẽ tạo phản hồi và gửi lại cho chúng tôi dưới dạng danh sách tất cả người dùng hiện có (tất nhiên nếu họ có trong cơ sở dữ liệu). Và họ đây rồi! Ваше первое приложение с использованием Java-сервлетов - 12Hãy thử xóa một trong những người dùng: Ваше первое приложение с использованием Java-сервлетов - 13Nó cũng hoạt động! Vì vậy, chúng tôi đã viết ứng dụng đầu tiên của mình bằng cách sử dụng servlet. Như bạn có thể thấy, mọi thứ hóa ra không quá khó :) Ví dụ, như bài tập về nhà, bạn có thể trả lại chức năng làm việc với ô tô từ bài viết trước vào ứng dụng. Những thứ kia. tạo một trang servlet và jsp riêng cho ô tô và hướng dẫn ứng dụng của chúng tôi hiển thị danh sách ô tô của người dùng, thêm ô tô mới cho anh ta cũng như chỉnh sửa và xóa chúng. PS Servlets và JSP là những công nghệ khá cổ xưa và trên Internet, bạn thường có thể tìm thấy những bình luận với tinh thần “ai cần thứ rác rưởi này?” Câu trả lời khá đơn giản - nó chủ yếu cần thiết cho những người sẽ làm việc trong các dự án thực tế, trong đó rất có thể sẽ có rất nhiều mã được viết bằng cách sử dụng chúng. Và việc xẻ “thứ cũ” thành thứ mới mà không hiểu cách thức hoạt động của nó vẫn là một thú vui :) Để nghiên cứu kỹ hơn về chủ đề JSP và servlet, bạn có thể sử dụng cuốn “Head First Servlets and JSP” (trong Chỉ tiếng Anh). Nó được viết bởi cùng các tác giả với siêu sách nổi tiếng "Head First Java", mà đối với nhiều người có thể là sự đảm bảo về chất lượng :) Tôi hy vọng bài viết này hữu ích cho độc giả! Nếu bạn muốn xem các bài viết mới, đừng quên ủng hộ tác giả trong cuộc thi bằng cách "Like" anh ấy. Hoặc tốt hơn nữa - “Tôi rất thích nó” :) Cảm ơn bạn đã quan tâm và chúc bạn học tập may mắn!
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION