CodeGym /مدونة جافا /Random-AR /تطبيقك الأول باستخدام Java servlets
John Squirrels
مستوى
San Francisco

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

نشرت في المجموعة
أهلا بالجميع! سوف تتعرف على servlets كمفهوم أساسي لتطوير الويب، وستكون قادرًا على كتابة تطبيق بسيط يستخدمها. تطبيقك الأول باستخدام Java servlets - 1 لتجنب الإجراءات غير الضرورية، لن نبدأ من الصفر. سنواصل العمل على تطبيقنا من مقالتي السابقة حول السبات . ولكن بما أننا بدأنا للتو في التعرف على servlets، فقد قمت بإزالة كل ما يتعلق بالفئة Auto من التطبيق وتركت فقط فئة المستخدم والإجراءات التي تتضمنها. سيتم تنظيم المشروع على النحو التالي: تطبيقك الأول باستخدام Java servlets - 2إذن، servlets! تنص ويكيبيديا على ما يلي: "إن Java servlet هو أحد مكونات برنامج Java الذي يعمل على توسيع إمكانيات الخادم. على الرغم من أن servlet يمكنها الاستجابة لأنواع عديدة من الطلبات، إلا أنها في الغالب تنفذ حاويات الويب لاستضافة تطبيقات الويب على خوادم الويب وبالتالي فهي مؤهلة كخادم- واجهة برمجة تطبيقات ويب servlet الجانبية." هذا صحيح تماما. هنا، ولأول مرة، نواجه مفهوم "بنية تطبيق خادم العميل". إنها بسيطة جدًا في جوهرها. يصل العميل إلى الخادم عن طريق إرسال طلب 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. الربيع 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: doPost()، doGet()، doPut() و doDelete(). لقد سمحوا لنا بإنشاء المستخدمين وقراءتهم وتحديثهم وحذفهم. تقبل الطرق مثيلات الفئات javax.servlet.http.HttpServletRequest وjavax.servlet.http.HttpServletResponse كمدخلات، أي الطلبات المرسلة إلى الخادم والاستجابات التي يتلقاها العميل. داخليًا، تستدعي الطرق الطرق ذات الصلة لفئة UserService، ويتم إنشاء استجابة للعميل وإعادة توجيهها إلى عنوان URL /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>Hello!</title>
</head>
<body>
If you want to start working with the user database,<br>
click the button below:

<form action = "users" method="get">
    <input type="submit" value="Start working with database">
</form>
</body>
</html>
addUser.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Add new user</title>
</head>
<body>
<form action = "/users" method="post">
    <input required type="text" name="name" placeholder="Name">
    <input required type="text" name="age" placeholder="Age">
    <input type="submit" value="Save">
</form>
</body>
</html>
deleteUser.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Delete user</title>
</head>
<body>

Are you sure you want to delete the user ${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="Delete">
</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>User list</title>
</head>
<body>
<table border="2">
    <tr>
        <td>ID</td>
        <td>Name</td>
        <td>Age</td>
        <td>Actions</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="Modify" style="float:left">
                </form>
                <form action="deleteUser.jsp" method="post">
                    <input type="hidden" name="id" value="${user.getId()}">
                    <input type="submit" value="Delete" style="float:left">
                </form></td>
        </tr>
    </c:forEach>
</table>

<form action = "addUser.jsp">
    <input type="submit" value="Add new user">
</form>
</body>
</html>
updateUser.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Modify user data</title>
</head>
<body>

Edit user

<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="Update">
</form>

</body>
</html>
تحتوي صفحة JSP (صفحة JavaServer) على نوعين من النص: بيانات المصدر الثابتة التي يمكن تنسيقها كنص (HTML أو SVG أو WML أو XML)، وعناصر JSP المستخدمة لإنشاء محتوى ديناميكي. لمساعدتك في فهم ماهية صفحة JSP، قمت بنسخ مقطع من مقالة جيدة جدًا. "في الأساس، في المرة الأولى التي يتم فيها طلب JSP، يتحول إلى servlet ويعمل كـ servlet. من المهم جدًا فهم هذا. صفحة JSP ليست مثل صفحة HTML - يجب على المبرمج المبتدئ أن يفهم بوضوح أن هذه servlet أخرى - كل ما في الأمر أنك لا تحتاج إلى برمجة كيفية عرضها. يمكن ببساطة رسمها وإضافة البيانات عند الضرورة. ولكن نظرًا لأن صفحة JSP تذكرنا بـ HTML، فمن الواضح أن المصمم سيجد الأمر أسهل. ومرة ​​أخرى نؤكد بشدة للمبتدئين أن صفحة JSP هي Servlet . يتم إنشاؤها، بما في ذلك إضافة جميع البيانات، على الخادم. وهذا هو المكان الذي يتم فيه إدراج جميع البيانات. وفي المتصفح، يحصل المستخدم على صفحة HTML النهائية، والتي تحتوي على ليست علامات جافا." يمكنك التأكد من أن صفحة JSP هي في الواقع servlet، لأن كل صفحة لها طريقة يجب تنفيذها. على سبيل المثال، يشير ملف Index.jsp إلى أنه عند النقر فوق الزر "بدء العمل مع قاعدة البيانات"، سيتم تنفيذ طريقة get (method = "get"). تقوم صفحة addUser.jsp، المسؤولة عن إنشاء مستخدمين جدد، بتنفيذ طريقة النشر (method = "post") عند النقر فوق زر الحفظ. تتكون بقية صفحة JSP من علامات HTML ثابتة عادية، لذا لن نتناولها بالتفصيل. هذا موضوع لمقال آخر وهناك الكثير حول هذا الموضوع على الإنترنت. لذلك، قمنا بإنشاء التطبيق لدينا! الآن نحن بحاجة لاختباره في العمل! للقيام بذلك، نحتاج إلى حاوية Apache Tomcat servlet المذكورة أعلاه. يمكنك تنزيل الحاوية من الموقع الرسمي (أستخدم الإصدار 8). بعد ذلك، نحتاج إلى إنشاء تكوين في IDEA لتشغيل تطبيقنا من خلال Tomcat. للقيام بذلك، افتح علامة التبويب "تحرير التكوينات"، تطبيقك الأول باستخدام Java servlets - 3وقم بإنشاء تكوين جديد، تطبيقك الأول باستخدام Java servlets - 4ثم حدد "Tomcat Server Local". في علامة التبويب "خادم التطبيقات"، حدد المسار إلى مجلد Tomcat تطبيقك الأول باستخدام Java servlets - 5. بعد ذلك، انتقل إلى علامة التبويب "النشر". تطبيقك الأول باستخدام Java servlets - 6هنا، نقوم بتهيئة نشر تطبيقنا على الخادم المحلي. اضغط على "+"، وحدد "Artifact" -> YourProjectName:war (سنقوم بإنشاء التطبيق إلى ملف حرب). تطبيقك الأول باستخدام Java servlets - 7وأن حوالي يلخص الامر! في صفحة "الخادم"، يمكنك أن ترى أن تطبيقنا سيتم تشغيله على http://localhost:8080/. احفظ التكوين وأعطيه اسمًا (أسمي التكوين الخاص بي "تومي"). بعد ذلك، في علامة التبويب Maven في IDEA (على الجانب الأيمن)، سنستخدم البرنامج الإضافي war لبناء مشروعنا في ملف حرب (المكونات الإضافية -> الحرب -> الحرب: الحرب). تطبيقك الأول باستخدام Java servlets - 8بعد اكتمال البناء، قم بتشغيل التطبيق وانتظر. نجاح! تم إطلاق صفحة البداية. الآن نضغط على زر "بدء العمل مع قاعدة البيانات". سيقوم ملف Index.jsp الخاص بنا بإنشاء طلب GET الذي سيتم معالجته بواسطة الخادم. سيقوم الخادم بإنشاء استجابة وإعادتها إلينا في شكل قائمة بجميع المستخدمين الحاليين (بافتراض وجود مستخدمين في قاعدة البيانات بالطبع). وها هم! أن هناك لديك! لقد كتبت تطبيقك الأول باستخدام Java servlets. تطبيقك الأول باستخدام Java servlets - 9 لم يكن ذلك سيئا للغاية، أليس كذلك؟ :) بالنسبة للواجبات المنزلية، يمكنك استعادة وظائف السيارة من المقالة السابقة . بمعنى آخر، قم بإنشاء صفحات servlet وJSP منفصلة للسيارات، وقم بتعليم التطبيق كيفية إدراج سيارات المستخدم، وإضافة سيارات جديدة إلى المستخدم، وتحريرها وحذفها. تعد PS Servlets وصفحات JavaServer من التقنيات القديمة إلى حد ما. على الإنترنت، يمكنك في كثير من الأحيان العثور على تعليقات مثل "من يحتاج إلى هذه القمامة القديمة؟" الجواب بسيط للغاية: معظمهم من الأشخاص الذين سيعملون في مشاريع حقيقية، حيث من المحتمل جدًا أن يواجهوا الكثير من الأكواد البرمجية التي تستخدم هذه التقنيات. وحتى بدون فهم كيفية عملها، لا يزال من الممتع تقطيع "الخردة القديمة" إلى شيء جديد :) للحصول على دراسة أكثر شمولاً لـ JSP وservlets، يمكنك الرجوع إلى كتاب "Head First Servlets and JSP " . لقد كتبه نفس مؤلفي الكتاب الرائع الشهير "Head First Java"، والذي سيعتبره الكثيرون ضمانًا للجودة :) آمل أن يكون هذا المقال مفيدًا! شكرا لاهتمامكم، ونتمنى لك حظا سعيدا في التعلم!
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION