CodeGym /בלוג Java /Random-HE /היישום הראשון שלך המשתמש בשרתים של Java
John Squirrels
רָמָה
San Francisco

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

פורסם בקבוצה
שלום לכולם! תכירו servlets כמושג בסיסי של פיתוח אתרים, ותוכלו לכתוב אפליקציה פשוטה שמשתמשת בהם. היישום הראשון שלך המשתמש בשרתים של Java - 1 כדי למנוע פעולות מיותרות, לא נתחיל מאפס. נמשיך לעבוד על היישום שלנו מהמאמר הקודם שלי על Hibernate . אבל מכיוון שרק התחלנו להכיר servlets, הסרתי את כל מה שקשור למחלקה Auto מהאפליקציה והשארתי רק את המחלקה User ופעולות הקשורות בה. הפרויקט יהיה בנוי כך: היישום הראשון שלך המשתמש בשרתים של Java - 2אז, servlets! ויקיפדיה קובעת: "סרבלט Java הוא רכיב תוכנת Java שמרחיב את היכולות של שרת. למרות שסרבלטים יכולים להגיב לסוגים רבים של בקשות, הם לרוב מיישמים קונטיינרים אינטרנטיים לאירוח יישומי אינטרנט בשרתי אינטרנט ובכך מתאימים כשרת- servlet web API." זה בדיוק נכון. כאן, לראשונה, אנו נתקלים במושג של "ארכיטקטורת יישומי שרת-לקוח". זה די פשוט בבסיסו. הלקוח ניגש לשרת על ידי שליחת בקשת 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. נצטרך שיעור אביב אחד, עליו נדבר מעט מאוחר יותר.
ניהול ה-servlet מטופל על ידי מיכל ה-servlet. במקרה שלנו, נשתמש ב- Apache Tomcat. זה די פופולרי - בטח כבר שמעתם על זה :) מחזור החיים של ה-servlet מורכב מהשלבים הבאים:
  1. אם אין servlet במיכל:
    • מחלקת ה-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: doPost(), doGet(), doPut() ו-doDelete(). הם מאפשרים לנו ליצור, לקרוא, לעדכן ולמחוק משתמשים. השיטות מקבלות מופעים של מחלקות javax.servlet.http.HttpServletRequest ו-javax.servlet.http.HttpServletResponse כקלט, כלומר בקשות שנשלחות לשרת ותגובות שהתקבלו על ידי הלקוח. באופן פנימי, המתודות מתקשרות לשיטות הרלוונטיות של המחלקה UserService, ותגובה עבור הלקוח נוצרת ומופנית לכתובת /users URL. לדוגמה, בשיטת doGet() אנו מקבלים רשימה של כל המשתמשים. לאחר מכן, אנו יוצרים אובייקט RequestDispatcher, המאפשר לנו לכלול אובייקטים בבקשת HTTP ולהפנות אותו למשאב ספציפי (לדוגמה, לעמוד JSP של לקוח). בשיטת doPut() (המעדכנת את נתוני המשתמש), אנו מעבדים בקשת HTTP, מחלצים את הפרמטרים המזהה, השם והגיל, מוצאים את המשתמש עם המזהה שצוין, מקצה לו את השם והגיל שבבקשה ומחזירים לדף /users. אבל כדי שכל השיטות הללו יפעלו כהלכה, עלינו להגדיר את ה-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. אך ניתן להשתמש רק בבקשות 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 (שיטה = "get"). הדף addUser.jsp, שאחראי על יצירת משתמשים חדשים, מבצע את שיטת הפוסט (שיטה = "פוסט") כאשר אתה לוחץ על כפתור השמירה. שאר עמוד ה-JSP מורכב מסימון HTML סטטי רגיל, כך שלא נתעכב עליו. זה נושא למאמר אחר ויש הרבה על הנושא הזה באינטרנט. אז, יצרנו את האפליקציה שלנו! עכשיו אנחנו צריכים לבדוק את זה בפעולה! לשם כך, אנו זקוקים למיכל השרתים של Apache Tomcat שהוזכר לעיל. אתה יכול להוריד את המיכל מהאתר הרשמי (אני משתמש בגרסה 8). לאחר מכן, עלינו ליצור תצורה ב-IDEA כדי להפעיל את האפליקציה שלנו דרך Tomcat. כדי לעשות זאת, פתח את הכרטיסייה "ערוך תצורות", היישום הראשון שלך המשתמש בשרתים של Java - 3צור תצורה חדשה היישום הראשון שלך המשתמש בשרתים של Java - 4ובחר "Tomcat Server Local". בכרטיסייה "שרת יישומים", ציין את הנתיב לתיקיית Tomcat. היישום הראשון שלך המשתמש בשרתים של Java - 5לאחר מכן, עבור ללשונית "פריסה". היישום הראשון שלך המשתמש בשרתים של Java - 6כאן, אנו מגדירים את הפריסה של האפליקציה שלנו בשרת המקומי. לחץ על "+", בחר "Artifact" -> YourProjectName:war (אנחנו נבנה את האפליקציה לקובץ מלחמה). היישום הראשון שלך המשתמש בשרתים של Java - 7וזה בערך מסכם את זה! בדף "שרת", אתה יכול לראות שהאפליקציה שלנו תפעל בכתובת http://localhost:8080/. שמור את התצורה ותן לה שם (אני קורא לתצורה שלי "טומי"). לאחר מכן, בלשונית Maven ב-IDEA (בצד ימין), נשתמש בתוסף המלחמה כדי לבנות את הפרויקט שלנו לקובץ מלחמה (תוספים -> מלחמה -> מלחמה: מלחמה). היישום הראשון שלך המשתמש בשרתים של Java - 8לאחר השלמת הבנייה, הפעל את היישום והמתן. הַצלָחָה! דף הפתיחה הושק. כעת אנו לוחצים על כפתור "התחל לעבוד עם מסד הנתונים". index.jsp שלנו יפיק בקשת GET שתעובד על ידי השרת. השרת יפיק תגובה ויחזיר לנו אותה בצורה של רשימה של כל המשתמשים הקיימים (בהנחה שיש משתמשים במסד הנתונים כמובן). והנה הם! זה יש לך את זה! כתבת את היישום הראשון שלך באמצעות servlets של Java. היישום הראשון שלך המשתמש בשרתים של Java - 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