JavaRush /בלוג Java /Random-HE /היישום הראשון שלך המשתמש בשרתים של Java

היישום הראשון שלך המשתמש בשרתים של Java

פורסם בקבוצה
שלום לכולם! במאמר זה, תכירו את הרעיון הבסיסי של פיתוח אתרים של servlets ותוכלו לכתוב אפליקציה פשוטה באמצעותם. היישום הראשון שלך המשתמש בשרתים של Java - 1כדי למנוע צעדים מיותרים, לא נתחיל מאפס, ונמשיך לעבוד על האפליקציה שלנו מהמאמר הקודם שלי על Hibernate . עם זאת, מכיוון שאנחנו רק התחלנו עם servlets, הסרתי את כל מה שקשור למחלקה Auto מהאפליקציה והשארתי רק את המחלקה User ופעולותיה. מבנה הפרויקט ייראה כך: היישום הראשון שלך המשתמש בשרתים של Java - 2אז, servlets! ויקיפדיה אומרת: "סרבלט הוא ממשק ג'אווה שהטמעתו מרחיבה את הפונקציונליות של השרת. סרבלט מקיים אינטראקציה עם לקוחות באמצעות עיקרון של בקשה-תגובה." ואכן כך הוא. כאן אנו נתקלים לראשונה במושג "ארכיטקטורת יישומי שרת-לקוח". המהות שלו די פשוטה ומשתלבת בתמונה אחת (שנלקחה מכאן ).
היישום הראשון שלך באמצעות Java Servlets - 3
הלקוח יוצר קשר עם השרת על ידי שליחת בקשת HTTP. השרת מייצר את הנתונים הדרושים (לדוגמה, מקבל אותם ממסד הנתונים) ומחזיר אותם ללקוח. הדוגמה הפשוטה ביותר: ברשת חברתית מסוימת לוחצים על כפתור "חברים" וכך שולחים בקשה לשרת. השרת בודק את רשימת החברים שלך במסד הנתונים ומחזיר אותה אליך (ללקוח). רשימת בקשות ה-HTTP היא די גדולה, אבל אם מעולם לא נתקלתם בהן, אז להבנה טובה יותר עדיף לקרוא עליהן, למשל, כאן . המשימה שלנו היא: ליצור יישום CRUD באמצעות servlets. היישום חייב להיות מסוגל ליצור, לשנות ולמחוק משתמשים ממסד הנתונים באמצעות servlet שמעבד בקשות HTTP. האפליקציה שלנו מהמאמר על 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. נצטרך שיעור אביב אחד, עליו נדבר מעט מאוחר יותר.
הפעולה של servlets מנוהלת על ידי מיכל ה-servlet. במקרה שלנו נשתמש ב- Apache Tomcat. דבר די פופולרי, ובטח כבר שמעתם עליו :) מחזור החיים של סרבלט מורכב מהשלבים הבאים:
  1. אם אין סרבלט במיכל.
    • מחלקת ה-servlet נטען על ידי המכולה.
    • המיכל יוצר מופע של מחלקת ה-servlet.
    • הקונטיינר קורא לשיטת init() . שיטה זו מאתחלת את ה-servlet ונקראת תחילה לפני שה-servlet יכול לתת שירות בקשות. שיטת init() נקראת פעם אחת בלבד במהלך כל מחזור החיים שלה.
  2. מתן בקשת לקוח. כל בקשה מעובדת בשרשור נפרד משלה. הקונטיינר קורא לשיטת service() עבור כל בקשה. שיטה זו קובעת את סוג הבקשה הנכנסת ומפיצה אותה לשיטה המתאימה לסוג זה לעיבוד הבקשה. מפתח ה-servlet חייב לספק יישומים לשיטות אלו. אם מתקבלת בקשה שעבורה לא מיושמת מתודה, השיטה של ​​מחלקת האב נקראת ובדרך כלל מסתיימת בשגיאה שהוחזרה למבקש.
  3. במקרה שהמכל צריך למחוק servlet, הוא קורא לשיטת destroy() אשר מסירה את ה-servlet מהשירות. כמו שיטת init(), גם שיטה זו נקראת פעם אחת במהלך כל מחזור ה-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, מחלצים ממנה את המזהה, השם והגיל, מוצאים את המשתמש עם המזהה שצוין, מקצה לו את השם והגיל שהגיעו איתו ב- בקשה, וחזור לדף /משתמשים. עם זאת, כדי שכל השיטות הללו יפעלו כהלכה, עלינו להגדיר את ה-servlet. לשם כך אנו משתמשים בקובץ web.xml בתיקיית 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>
כל התגים בקובץ הזה הם, באופן עקרוני, אינטואיטיביים, אבל בואו נעבור עליהם ברצף. <welcome-file-list> - מצוין דף ה-JSP ההתחלתי, שייפתח ראשון עם הפעלת האפליקציה. במקרה שלנו, זה העמוד index.jsp. <servlet> - רישום המחלקה UserSimpleServlet שלנו בתור servlet. <servlet-mapping> הוא תג חשוב מאוד. זה מגדיר את כתובות האתרים שיעובדו על ידי ה-servlet. במקרה שלנו, כל אלה הן כתובות אתרים, אז אנחנו פשוט מציינים "/". אבל, למשל, אם היה לנו אפליקציה עם משתמשים והמכונות שלהם, אז נוכל ליצור servlet שני - SimpleAutoServlet. אז המיפוי עבור servlet המשתמש יהיה "/users" (כלומר, בקשות הקשורות לעיבוד משתמשים), ועבור ה-servlet האוטומטי זה יהיה "/autos". ולבסוף, <פילטר>. הוא מגדיר באופן פנימי אובייקט של המחלקה org.springframework.web.filter.HiddenHttpMethodFilter. המאמר לא נוגע לאביב, אז אני לא אדבר עליו בפירוט. הרשו לי רק לומר שהוא מצורף לאפליקציה שלנו רק כתכונה נוספת. הנקודה היא שנשתמש בדפי JSP כדי ליצור את צד הלקוח. הנתונים שלנו יוצגו בעמוד כטבלה עם רשימת משתמשים. בתוך דפי JSP, תגי HTML <form/> ישמשו. ורק בקשות HTTP GET ו-POST ניתן להשתמש כדי לשלוח נתונים מ-<form/>. כלומר, עבור כל שלוש הפעולות - עדכון, מחיקה ויצירת משתמש - נצטרך להשתמש רק בבקשות POST. שימוש בבקשות PUT ו-DELETE לא יהיה זמין עבורנו. ובאופן עקרוני, זה די נורמלי וקל ליישום, אבל המחלקה HiddenHttpMethodFilter מאפשרת לנו להשתמש בהם. זה יהפוך את ההבדלים בין הפעולות באפליקציה לברורים יותר לקורא. לבסוף, בואו נעבור לצד הלקוח. הוא מיוצג על ידי חמישה דפי JSP. index.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>
deleteUser.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>
updateUser.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) מכיל שני סוגי טקסט: נתוני מקור סטטיים, שיכולים להיות באחד מפורמטי הטקסט (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 סטטי רגיל, ולכן לא נתעכב עליהם בפירוט - זה הנושא של מאמר נפרד, שיש הרבה ממנו באינטרנט. אז, יצרנו את האפליקציה שלנו, כל מה שנותר הוא לבדוק אותה בפעולה! לשם כך, נצטרך את מיכל השרתים של Apache Tomcat שהוזכר לעיל. אתה יכול להוריד את החתול מהאתר הרשמי (אני משתמש בגרסה 8). לאחר מכן, עלינו ליצור תצורה ב-IDEA כדי להפעיל את האפליקציה שלנו באמצעות Tomcat. כדי לעשות זאת, פתח את הכרטיסייה "ערוך תצורות", היישום הראשון שלך באמצעות Java Servlets - 4צור תצורה חדשה היישום הראשון שלך באמצעות Java Servlets - 5ובחר Tomcat Server Local. בלשונית Application Server, ציין את הנתיב לתיקיה שבה נמצא Tomcat. היישום הראשון שלך באמצעות Java Servlets - 6לאחר מכן, עבור ללשונית Deployment. Ваше первое приложение с использованием Java-сервлетов - 7כאן אנו מגדירים את הפריסה של האפליקציה שלנו בשרת מקומי. לחץ על "+", בחר "Artifact" -> שם הפרויקט שלך: war (נרכיב את היישום לקובץ מלחמה). Ваше первое приложение с использованием Java-сервлетов - 8זה בעצם זה! בעמוד "שרת" תוכלו לראות שאותה אפליקציה תפעל ב-"http://localhost:8080/". שמור את התצורה הזו ושם לה משהו (שם התצורה שלי הוא "טומי"). לאחר מכן, בלשונית Maven ב-IDEA (בצד ימין) נשתמש בתוסף המלחמה כדי לבנות את הפרויקט שלנו לקובץ מלחמה (תוספים -> מלחמה -> מלחמה: מלחמה). Ваше первое приложение с использованием Java-сервлетов - 9Ваше первое приложение с использованием Java-сервлетов - 10הַצלָחָה! דף הפתיחה הושק. כעת לחץ על כפתור "התחל לעבוד עם מסד הנתונים". דף ה-JSP שלנו index.jsp יפיק בקשת GET שתעובד על ידי השרת. השרת יפיק תגובה ויחזיר לנו אותה בצורה של רשימה של כל המשתמשים הקיימים (אם הם כמובן נמצאים במסד הנתונים). והנה הם כאן! Ваше первое приложение с использованием Java-сервлетов - 12בואו ננסה למחוק את אחד מהמשתמשים: Ваше первое приложение с использованием Java-сервлетов - 13גם זה עובד! אז כתבנו את האפליקציה הראשונה שלנו באמצעות servlets. כפי שאתה יכול לראות, הכל התברר כל כך לא קשה :) בתור שיעורי בית, אתה יכול, למשל, להחזיר את הפונקציונליות של עבודה עם מכוניות מהמאמר הקודם לאפליקציה. הָהֵן. צור דפי servlet ו-jsp נפרדים למכוניות וללמד את האפליקציה שלנו להציג רשימה של מכוניות המשתמש, להוסיף לו מכוניות חדשות, כמו גם לערוך ולמחוק אותן. PS Servlets ו-JSP הם טכנולוגיות עתיקות למדי, ובאינטרנט אתה יכול למצוא לעתים קרובות הערות ברוח "מי צריך את הזבל הזה?" התשובה די פשוטה - היא נחוצה בעיקר למי שיעבוד על פרויקטים אמיתיים, שבהם בהחלט ייתכן שיהיה הרבה קוד שנכתב באמצעותם. ולנסור "דברים ישנים" למשהו חדש, מבלי להבין איך זה עובד, זה עדיין תענוג :) ללימוד מעמיק יותר של הנושא של JSP ו-servlets, אתה יכול להשתמש בספר "Head First Servlets and JSP" (ב רק אנגלית). הוא נכתב על ידי אותם מחברים כמו ספר העל המפורסם "Head First Java", אשר עבור רבים יכול להיות ערובה לאיכות :) אני מקווה שמאמר זה היה שימושי לקוראים! אם תרצו לראות מאמרים חדשים, אל תשכחו לתמוך בכותב בתחרות על ידי "אהבתי" אותו. או יותר טוב - "אני אוהב את זה מאוד" :) תודה על תשומת הלב, ובהצלחה בלימודים!
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION