JavaRush /مدونة جافا /Random-AR /تطبيقك الأول باستخدام Java servlets

تطبيقك الأول باستخدام Java servlets

نشرت في المجموعة
أهلاً بكم! في هذه المقالة، سوف تتعرف على المفهوم الأساسي لتطوير الويب الخاص بـ servlets وستكون قادرًا على كتابة تطبيق بسيط باستخدامها. تطبيقك الأول باستخدام Java servlets - 1لتجنب الخطوات غير الضرورية، لن نبدأ من الصفر، وسنواصل العمل على تطبيقنا من مقالتي السابقة حول السبات . ومع ذلك، نظرًا لأننا بدأنا للتو في استخدام servlets، فقد قمت بإزالة كل ما يتعلق بالفئة Auto من التطبيق وتركت فقط فئة المستخدم وإجراءاتها. سيبدو هيكل المشروع كما يلي: تطبيقك الأول باستخدام Java servlets - 2إذن، servlets! تقول ويكيبيديا: "إن servlet عبارة عن واجهة Java التي يعمل تنفيذها على توسيع وظائف الخادم. ويتفاعل servlet مع العملاء من خلال مبدأ الاستجابة للطلب." وهو بالفعل كذلك. هنا نواجه أولاً مفهوم "هندسة تطبيقات خادم العميل". جوهرها بسيط للغاية ويتناسب مع صورة واحدة (مأخوذة من هنا ).
تطبيقك الأول باستخدام Java Servlets - 3
يتصل العميل بالخادم عن طريق إرسال طلب HTTP. يقوم الخادم بإنشاء البيانات الضرورية (على سبيل المثال، استلامها من قاعدة البيانات) وإعادتها إلى العميل. أبسط مثال: في شبكة اجتماعية معينة، تقوم بالنقر فوق زر "الأصدقاء" وبالتالي إرسال طلب إلى الخادم. يتحقق الخادم من قائمة أصدقائك في قاعدة البيانات ويعيدها إليك (العميل). قائمة طلبات HTTP كبيرة جدًا، ولكن إذا لم تواجهها من قبل، فمن الأفضل أن تقرأ عنها من أجل فهم أفضل، على سبيل المثال، هنا . مهمتنا هي: إنشاء تطبيق CRUD باستخدام servlets. يجب أن يكون التطبيق قادرًا على إنشاء المستخدمين وتعديلهم وحذفهم من قاعدة البيانات باستخدام servlet الذي يعالج طلبات HTTP. تطبيقنا من المقالة حول السبات يعرف بالفعل كيفية القيام بذلك، ولكن تم التحكم فيه مباشرة من كود Java، وبشكل أكثر دقة، من الطريقة الرئيسية (). هنا سيتم إرسال الطلبات من قبل العميل، أي أنت :) أول شيء يتعين علينا القيام به هو إضافة تبعيات جديدة إلى ملف 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. الربيع WebMVC. سنحتاج إلى فصل ربيعي واحد سنتحدث عنه بعد قليل.
تتم إدارة تشغيل servlet بواسطة حاوية servlet. في حالتنا سوف نستخدم Apache Tomcat. شيء شائع جدًا، وربما سمعت عنه بالفعل :) تتكون دورة حياة servlet من الخطوات التالية:
  1. إذا لم يكن هناك servlet في الحاوية.
    • يتم تحميل فئة servlet بواسطة الحاوية.
    • تقوم الحاوية بإنشاء مثيل لفئة servlet.
    • تستدعي الحاوية طريقة init (). تقوم هذه الطريقة بتهيئة servlet ويتم استدعاؤها أولاً قبل أن يتمكن servlet من خدمة الطلبات. يتم استدعاء الأسلوب init () مرة واحدة فقط خلال دورة حياته بأكملها.
  2. خدمة طلب العميل. تتم معالجة كل طلب في موضوع منفصل خاص به. تستدعي الحاوية طريقة الخدمة () لكل طلب. تحدد هذه الطريقة نوع الطلب الوارد وتوزعه على الطريقة المقابلة لهذا النوع لمعالجة الطلب. يجب على مطور servlet توفير تطبيقات لهذه الأساليب. إذا تم تلقي طلب لم يتم تنفيذ طريقة له، فسيتم استدعاء طريقة الفئة الأصلية وتنتهي عادةً بإرجاع خطأ إلى الطالب.
  3. في حالة احتياج الحاوية إلى حذف servlet، فإنها تستدعي طريقة التدمير () التي تزيل 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، واستخراج المعرف والاسم ومعلمات العمر منه، والعثور على المستخدم بالمعرف المحدد، وتعيين له الاسم والعمر الذي جاء معه في الطلب والعودة إلى الصفحة /المستخدمين. ومع ذلك، لكي تعمل كل هذه الطرق بشكل صحيح، نحتاج إلى تكوين 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> هي علامة مهمة جدًا. فهو يحدد عناوين URL التي سيتم معالجتها بواسطة servlet. في حالتنا، هذه كلها عناوين URL، لذلك نشير ببساطة إلى "/". ولكن، على سبيل المثال، إذا كان لدينا تطبيق مع المستخدمين وأجهزتهم، فيمكننا إنشاء servlet ثانٍ - SimpleAutoServlet. بعد ذلك، سيكون التعيين لـ servlet المستخدم هو "/users" (أي الطلبات المتعلقة بمعالجة المستخدمين)، وبالنسبة لـ servlet التلقائي سيكون "/autos". وأخيرًا، <filter>. فهو يحدد داخليًا كائنًا من فئة 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 على أنه عند النقر فوق الزر "بدء العمل مع قاعدة البيانات"، سيتم تنفيذ الطريقة = "get". في صفحة addUser.jsp المسؤولة عن إنشاء مستخدم جديد، عند الضغط على زر الحفظ، سيتم تنفيذ الطريقة = "post". يتكون باقي JSP من علامات HTML ثابتة عادية، لذلك لن نتناولها بالتفصيل - هذا هو موضوع مقالة منفصلة يوجد الكثير منها على الإنترنت. لذلك، قمنا بإنشاء تطبيقنا، كل ما تبقى هو اختباره عمليًا! للقيام بذلك، سنحتاج إلى حاوية Apache Tomcat servlet المذكورة أعلاه. يمكنك تنزيل القطة من الموقع الرسمي (أستخدم الإصدار 8). بعد ذلك، نحتاج إلى إنشاء تكوين في IDEA لتشغيل تطبيقنا عبر Tomcat. للقيام بذلك، افتح علامة التبويب "تحرير التكوينات"، تطبيقك الأول باستخدام Java Servlets - 4وقم بإنشاء تكوين جديد تطبيقك الأول باستخدام Java Servlets - 5وحدد Tomcat Server Local. في علامة التبويب "خادم التطبيق"، حدد المسار إلى المجلد الذي يوجد به Tomcat، تطبيقك الأول باستخدام Java Servlets - 6ثم انتقل إلى علامة التبويب "النشر". Ваше первое приложение с использованием Java-сервлетов - 7نقوم هنا بتكوين نشر تطبيقنا على خادم محلي. انقر فوق "+"، وحدد "قطعة أثرية" -> اسم مشروعك: war (سنقوم بتجميع التطبيق في ملف war). Ваше первое приложение с использованием Java-сервлетов - 8هذا هو الأساس! في صفحة "الخادم" يمكنك أن ترى أن نفس التطبيق سيتم تشغيله على "http://localhost:8080/". احفظ هذا التكوين وقم بتسميته بشيء ما (اسم التكوين الخاص بي هو "تومي"). بعد ذلك، في علامة التبويب Maven في IDEA (على الجانب الأيمن)، سنستخدم البرنامج الإضافي للحرب لبناء مشروعنا في ملف حرب (المكونات الإضافية -> الحرب -> الحرب: الحرب). Ваше первое приложение с использованием Java-сервлетов - 9Ваше первое приложение с использованием Java-сервлетов - 10نجاح! تم إطلاق صفحة البداية. الآن انقر على زر "بدء العمل مع قاعدة البيانات". سيقوم ملف Index.jsp الخاص بنا بصفحة JSP بإنشاء طلب GET والذي سيتم معالجته بواسطة الخادم. سيقوم الخادم بإنشاء استجابة وإعادتها إلينا في شكل قائمة بجميع المستخدمين الحاليين (إذا كانوا بالطبع موجودين في قاعدة البيانات). وها هم! Ваше первое приложение с использованием Java-сервлетов - 12دعونا نحاول حذف أحد المستخدمين: Ваше первое приложение с использованием Java-сервлетов - 13إنه يعمل أيضًا! لذلك قمنا بكتابة تطبيقنا الأول باستخدام servlets. كما ترون، كل شيء لم يكن صعبا للغاية :) كواجب منزلي، يمكنك، على سبيل المثال، إرجاع وظيفة العمل مع السيارات من المقالة السابقة إلى التطبيق. أولئك. إنشاء صفحات servlet و jsp منفصلة للسيارات وتعليم تطبيقنا عرض قائمة بسيارات المستخدم وإضافة سيارات جديدة إليه وتعديلها وحذفها. تعد PS Servlets و JSP من التقنيات القديمة جدًا، ويمكنك غالبًا العثور على تعليقات على الإنترنت بروح "من يحتاج إلى هذه الأشياء غير المرغوب فيها؟" الجواب بسيط للغاية - فهو مطلوب في المقام الأول من قبل أولئك الذين سيعملون في مشاريع حقيقية، حيث من الممكن جدًا أن يكون هناك الكثير من التعليمات البرمجية المكتوبة باستخدامها. ولا يزال نشر "الأشياء القديمة" إلى شيء جديد، دون فهم كيفية عملها، أمرًا ممتعًا :) للحصول على دراسة أكثر شمولاً لموضوع JSP وservlets، يمكنك استخدام كتاب "Head First Servlets وJSP" (في الانجليزية فقط). لقد كتبه نفس المؤلفين مثل الكتاب الرائع الشهير "Head First Java"، والذي يمكن أن يكون بالنسبة للكثيرين ضمانًا للجودة :) آمل أن يكون هذا المقال مفيدًا للقراء! إذا كنت ترغب في رؤية مقالات جديدة، لا تنسى دعم المؤلف في المسابقة عن طريق "الإعجاب" به. أو الأفضل من ذلك - "أنا أحب ذلك كثيرًا" :) شكرًا لك على اهتمامك، ونتمنى لك حظًا سعيدًا في دراستك!
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION