مخطط هيكل MVC الذي تم تنفيذه باستخدام Java Web كما يلي ، حيث يتم تنفيذ جزء وحدة التحكم باستخدام Servlet ، يتم تنفيذ جزء النموذج باستخدام Javabean ، ويتم تنفيذ معظم المشاهدات باستخدام صفحات JSP.
الأساس الأيديولوجي
يجب أن يكون مبدأ العمل لهيكل ثنائي الطبقات لـ JSP+Javabean مألوفًا نسبيًا وسهل الفهم.
ومع ذلك ، يجب أن يكون هناك شيء واحد هو أن المستخدم يرسل طلب صفحة ويب من خلال المتصفح. بعد وصول هذا الطلب إلى الخادم ، تم العثور على صفحة الويب المقابلة على جانب الخادم. إذا كان هذا هو الطلب الأول (لم يتم شرح المرة الثانية وتنفيذها) ، بالنسبة لـ JSP ، فمن الضروري إنشاء servlet ، ثم تنفيذ servlet من خلال محرك Servlet ، وتضمين نتيجة الاتصال Javabean في الصفحة وإعادته إلى متصفح المستخدم.
جوهر بنية الطبقات المكونة من ثلاث طبقات من JSP+Javabean+Servlet هو أن هناك وحدة تحكم إضافية: Servlet لتوزيع طلبات متصفح العميل. سيكون من المفيد فهم دور servlet الذي يعمل كوحدة تحكم كمعالجة مسبقة لطلب العميل. يمكن العثور على العلاقة المقابلة بين طلبات المستخدم و servlets محددة من خلال ملف تكوين web.xml. يحتوي كل Servlet على كائن Servlet محدد يتوافق معه ، وبالتالي فإن طلب المستخدم هو كائن Servlet الموروث من httpservlet.
!-JSPC Servlet Mappings Start-Servlet Servlet-Namems1/Servlet-Name Servlet-ClassNews.Firstaction/Servlet-Class/Servlet Servlet Servlet-Namems2/Servlet-Name-Name Servlet-classnews.detailaction/servlet-class/servlet! url-pattern/newsmain/url-pattern/servlet-mapping-mapping servlet-namems2/servlet-name-name-pattern/newsdetail/url-pattern/servlet mapping
كما هو موضح أعلاه ، قسم من تكوين servlet مستخرج من web.xml. يتم استخدام الجزء الأول بشكل أساسي لتكوين Servlet ليتم ربطه بكائن Servlet المحدد. يتم استخدام الجزء الثاني بشكل أساسي لتكوين أي Servlet تتم معالجته حسب الطلب. يرتبط ارتباط اسم servlet بكائن معالجة Servlet المحدد. على سبيل المثال ، تتم معالجة الطلب الذي أرسله متصفح العميل من /NewsMain بواسطة Servlet MS1. News.firstaction من Serlet Object.firstaction ، أي /newsmain-ms1-news.firstaction ، وهو معنى ملف التكوين. الآن بعد أن فهمت أن طلب المستخدم/الصحف سيتم معالجته بواسطة كائنات من فئة الأخبار. على سبيل المثال ، ما يلي هو تطبيق FirstAction.
يمتد الفئة النهائية الأولى في FirstAction httpservlet {خدمة void المحمية (httpservletrequest req ، httpservletresponse resp) رمي servletexception ، ioException {db db = new db () ؛ جلسة httpsession = req.getSession () ؛ حاول {session.setattribute (Constants.news_list_key ، news .SearchNewStitle (db)) ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ } db.close () ؛ سلسلة الهدف = "/p43_news/newsmain.jsp" ؛ Resp.SendRedirect (الهدف) ؛ }} من خلال هذا التنفيذ ، يمكننا أن نرى أنه عندما يتلقى الخادم طلب عميل لأداء news.searchNewStitle (DB) ، ثم يضع قيمة الإرجاع في الجلسة من خلال الجلسة. وبهذه الطريقة ، يمكن الحصول على القيمة المقابلة المخزنة في الجلسة من خلال Session.GetAttribute في NewsMain.jsp.
إذا نظرنا إلى الوراء ، فمن السهل أن نرى أن مبدأ العمل في JSP+Javabean يختلف عن JSP+Javabean+Servlet. يجب أن يضع الهيكل المكون من طبقتين المعالجة المسبقة في JSP ، على سبيل المثال ، News.SearchNewStitle (DB) ، وهيكل الطبقة المكونة من ثلاث طبقات يقوم أولاً بالمعالجة المسبقة في Servlet ، ثم يعادل إرجاع هذه النتيجة المعالجة إلى JSP من خلال الجلسة ، بحيث تبرز JSP المزيد من الاهتمام للواجهة.
متطلبات وحدة تسجيل تسجيل الدخول
1 سجل
1.1 نموذج تسجيل المستخدم (اسم المستخدم ، كلمة المرور ، البريد الإلكتروني ، اللقب ، رمز التحقق)
1.2 إرسال التسجيل: التحقق إلى (اسم المستخدم ، كلمة المرور ، البريد الإلكتروني ، اللقب ، رمز التحقق).
1.2.1 يتم الانتهاء من اسم المستخدم وكلمة المرور والبريد الإلكتروني واللقب في متصفح العميل وتطبيقه من خلال JS.
1.2.2 يجب إكمال رمز التحقق في البرنامج من جانب الخادم.
2. إذا تم تمرير التحقق من نموذج التسجيل ، فسيتم الحكم على منطق العمل.
2.1 إذا كان المستخدم موجودًا بالفعل ، فأخبر المستخدم رسالة الخطأ.
2.2 إذا كان عنوان البريد الإلكتروني موجودًا بالفعل ، فأخبر المستخدم رسالة الخطأ.
2.3 في حالة عدم وجود أي منها ، انتقل إلى الخطوة 3.
3. احفظ معلومات المستخدم إلى قاعدة البيانات
4. التسجيل بنجاح ، القفز إلى صفحة تسجيل الدخول
5. تسجيل الدخول
5.1 أرسل معلومات تسجيل الدخول الخاصة بالمستخدم إلى الخلفية للتحقق منها
5.2 إذا كان التحقق ناجحًا ، فانقل إلى الصفحة الرئيسية
5.3 إذا فشل القفز ، فانتقل إلى صفحة تسجيل الدخول ومطالبة برسالة خطأ.
هيكل دليل المشروع
يتم تقسيم التعليمات البرمجية المصدر للمشروع إلى أربعة ملفات حزم ، والتي يتم استخدامها للوصول إلى النماذج ، ومسافات ، وحدات تحكم ، وفئات الأدوات. الملفات المحددة هي كما يلي:
للعرض ، نحدد ثلاث صفحات JSP على النحو التالي:
تحديد العرض
صفحة login.jsp
<٪@ page language = "java" contentType = "text/html ؛ charset = utf-8" pageencoding = "utf-8" ٪> <! <html> <head> <meta http-equiv = "content-type" content = "text/html ؛ charset = utf-8"> <title> نموذج تسجيل الدخول </title> </head> <body> <font color = "red"> $ {message} </font> <a href = "regist.jsp" Action = "$ {pagecontext.request.contextpath}/login" method = "post"> username: <input type = "text" name = "username"> <bord/> كلمة المرور: <input type = "password"index.jsp صفحة
<٪@ page language = "java" contentType = "text/html ؛ charset = utf-8" pageencoding = "utf-8" ٪> <٪@ taglib uri = Transitional // en "" http://www.w3.org/tr/html4/loose.dtd "> } </font> <٪ if (request.getSession (). getAttribute ("username") == null) {response.sendRedirect ("login.jsp") ؛ } آخر {٪> <font color = "red"> "مرحبًا:" <٪ = request.getSession (). getAttribute ("username").صفحة regist.jsp
<٪@ page language = "java" contentType = "text/html ؛ charset = utf-8" pageencoding = "utf-8" ٪> <! <html> <head> <meta http-equiv = "content-type" content = "text/html ؛ charset = utf-8"> <title> نموذج مسجل للمستخدم </title> <script type = "text/javaScript"> changeimage () {document.geteLementbyid ("image"). }/checkimage؟ " + New Date (). getTime ()} دالة validateform () {// تحقق من اسم المستخدم ، كلمة المرور ، البريد الإلكتروني ، الاسم المستعار var username = document.getElementById ("اسم المستخدم"). القيمة ؛ if (username == "") {Alert ("لا يمكن أن يكون اسم المستخدم فارغًا") ؛ العودة كاذبة } var password = document.getElementById ("كلمة المرور"). القيمة ؛ if (password == "") {Alert ("لا يمكن أن تكون كلمة المرور فارغة") ؛ العودة كاذبة } var repassword = document.getElementById ("repassword"). value ؛ if (password! = repassword) {Alert ("يجب أن تكون كلمة المرور متسقة") ؛ العودة كاذبة } var nugname = document.getElementById ("lamname"). value ؛ if (lamname == "") {Alert ("لا يمكن أن يكون اللقب فارغًا") ؛ العودة كاذبة } // ^// s*// w+(؟: //. {0،1} [// w-]+)*@[a-za-z0-9] if (email.match ("^// s*// w+(؟: //. العودة كاذبة }} </script> </head> <body> <h3> جدول تسجيل المستخدم </h3> <font color = "red"> $ {message} </font> <form action = "$ {pagecontext.request.contextpath}/regist method = "post"> <table> <tr> <td> اسم المستخدم </td> <td> <td reput كلمة المرور </td> <td> <type type = "password" name = "repassword" id = "repassword"> </td> </tr> <td> <td> لقب </td> <td> <type type = "text" name = "namname" id = "namname"> </td> <tr> <td> <td> name = "email" id = "email"> </td> </tr> <tr> <td> رمز التحقق </td> <td> <type type = "text" name = "checkCode"> <img src = "$ {pageContext.Request.ContextPath}/checkimage" ystem = "pointer:" id = "image" onClick = "changeimage () ؛"> </td> </tr> <tr> <td> </td> <td> <type type = "إرسال" value = "التسجيل"> </td> </td> </table> </form> </toda> </html> تحديد النموذج
نموذج المستخدم:
حزمة com.vs2022.model ؛ مستخدم الفئة العامة {private string username ؛ كلمة مرور السلسلة الخاصة ؛ لقب السلسلة الخاصة البريد الإلكتروني الخاص بالسلسلة الخاصة ؛ // alt+ shft+ s // مربع حوار لطريقة الكتابة فوقها. السلسلة العامة getUserName () {return username ؛ } public void setusername (string username) {this.userName = username ؛ } السلسلة العامة getPassword () {return password ؛ } public void setPassword (سلسلة كلمة مرور) {this.password = password ؛ } السلسلة العامة getNickName () {return labes. } public void setNickName (سلسلة لقب) {this.nickName = nablemed ؛ } السلسلة العامة getEmail () {return email ؛ } public void setemail (string email) {this.email = email ؛ }}نموذج المستخدم
package com.vs2022.model ؛ import com.vs2022.Utils.dbutil ؛ useroperation useroperation {public final static int usernameExist = 1 ؛ int static int int static int int int 2 ؛ النجاح العام النهائي الثابت = 3 ؛ FANCTING FIND FANT FAIL = 4 ؛ تسجيل int العام (مستخدم المستخدم) {dbutil db = new dbutil () ؛ if (db.serchusername (user.getUserName ())) {// تشير إلى أن اسم المستخدم موجود بالفعل return usernameExist ؛ } if (db.serchemail (user.getEmail ())) {// يعني أن عنوان البريد الإلكتروني موجود بالفعل. إرجاع البريد الإلكتروني } // إذا كنت تمشي هنا ، فهذا يعني أنه لا يتم تخزين اسم مستخدم عنوان البريد الإلكتروني ، لذلك دعه يسجل. إضافة إلى قاعدة البيانات db.updateuser (المستخدم) ؛ العودة النجاح } public int login (user user) {dbutil db = new dbutil () ؛ if (db.loginsuccess (user.getUserName () ، user.getPassword ())) {// يعني أنه تم العثور على اسم المستخدم وكلمة المرور. نجاح العودة صحيح ؛ } عودة فشل ؛ }} طراز CheckCode
حزمة com.vs2022.model ؛ استيراد java.awt.color ؛ استيراد java.awt.font ؛ استيراد java.awt.graphics ؛ استيراد java.awt.image.bufferedImage ؛ استيراد java.io.ioException ؛ استيراد java.io.outputStream ؛ استيراد java.util.hashtable ؛ استيراد javax.imageio.imageio ؛ استيراد javax.servlet.servletexception ؛ استيراد javax.servlet.http.httpservletrequest ؛ استيراد javax.servlet.http.httpservletresponse ؛ استيراد javax.servlet.http.httpsession ؛ CheckCode الفئة العامة {private string getRandomString () {int rannum = (int) (Math.Random () * 9000) + 1000 ؛ return rannum + "" ؛} public void getCode (عرض int ، ارتفاع int ، httpservletrequest طلب ، httpservletresponse) يلقي servletexception ، ioException {// إنشاء صورة في صورة bufferedImage الذاكرة = جديد bufferedimage (العرض ، الطول ، bufferedimage.type_int_int_int_ergb) ؛ الرسومات g = image.getGraphics () ؛ // إنشاء كائن رسومات ، وظيفتها تعادل الفرشاة G.SetColor (color.getColor ("F8F8F8")) ؛ G.FillRect (0 ، 0 ، العرض ، الارتفاع) ؛ // ارسم خط الخلفية mfont = new font ("kaiti" ، font.bold ، 16) ؛ // تحديد نمط الخط G.SetFont (Mfont) ؛ // اضبط الخط G.SetColor (color.red) ؛ // إنشاء عدد عشوائي سلسلة Rans = getRandomString () ؛ // اكتب رقم عشوائي إلى جلسة httpsession session = request.getSession () ؛ session.setAttribute ("check" ، rans) ؛ // اكتب رقم عشوائي إلى Image G.DrawString (Rans ، 5 ، 20) ؛ // صورة فعالة G.Dispose () ؛ // إخراج صورة Imageio.write (صورة ، "JPEG" ، استجابة. getOutputStream ()) ؛}} تحديد وحدة التحكم
فئة Loginservlet
حزمة com.vs2022.controller ؛ استيراد java.io.ioException ؛ استيراد java.io.printwriter ؛ استيراد javax.servlet.servletexception ؛ استيراد javax.servlet.http.httpservlet ؛ استيراد javax.servlet.http.httpservletrequest ؛ استيراد javax.servlet.http.httpservelsponse ؛ COM.VS2022.MODEL.USEROPERATION ؛ فئة LoginServlet العامة يمتد httpservlet {public void doget (httpservletrequest request ، httpservletresponse) يلقي servleTexception ، ioException {// username username = request.getParameter ("username") ؛ سلسلة كلمة مرور = request.getParameter ("كلمة المرور") ؛ مستخدم المستخدم = مستخدم جديد () ؛ user.setUserName (اسم المستخدم) ؛ user.setPassword (كلمة المرور) ؛ // استدعاء وظيفة العمل Javabean لتنفيذ منطق العمل المحدد لتسجيل الدخول UserOperation US = جديد userOperation () ؛ // قيمة الإرجاع؟ int i = us.login (user) ؛ إذا كان (i == 4) {// يشير إلى أن تسجيل الدخول فشل ، كان اسم المستخدم أو كلمة المرور غير صحيح. request.getRequestDispatcher ("login.jsp"). } آخر {// تسجيل الدخول بنجاح ، القفز إلى الصفحة الرئيسية للموقع ، استخدم إعادة التوجيه // حفظ اسم المستخدم في طلب مجال الجلسة. استجابة. //request.getRequestDispatcher("index.jsp").forward(request ، response) ؛ }} public void dopost (httpservletrequest request ، httpservletresponse) يلقي servleTexception ، ioException {doget (request ، response) ؛ }}فئة Registservlet
حزمة com.vs2022.controller ؛ استيراد java.io.ioException ؛ استيراد javax.servlet.servletexception ؛ استيراد javax.servlet.http.httpservlet ؛ استيراد javax.servlet.http.httpservletrequest ؛ استيراد javax.servlet.http.httpservletresponse ؛ استيراد com.sun.org.apache.commons.beanutils.beanutils ؛ import com.vs2022.model.user استجابة httpservletresponse) يلقي servletexception ، ioException {// حل الرمز المشوهة request.setcharacterencoding ("utf-8") ؛ // أكمل التحقق من رمز التحقق checkcode = request.getParameter ("CheckCode") ؛ string check_code_session = (string) request.getSession (). getAttribute ("check") ؛ if (checkCode == null ||! checkcode.equals (check_code_session)) {// تشير إلى أن رمز التحقق يتم إدخاله بشكل غير صحيح. request.getRequestDispatcher ("regist.jsp"). إلى الأمام (طلب ، استجابة) ؛ يعود؛ } // إذا وصلت إلى هنا ، فهذا يعني أن جميع التحقق قد مرت ، وتتضمن المكالمة معالجة منطق الأعمال. مستخدم المستخدم = مستخدم جديد () ؛ . جرب {// Prerequisite: يجب أن يكون اسم حقل Javabean متسقًا مع مفتاح القيمة المقدمة في النموذج ، وإلا لا يمكن إكمال التغليف. BeanUtils.populate (المستخدم ، request.getParamEterMap ()) ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ رمي New RunTimeException ("آسف ، فشلت بيانات التغليف") ؛ } // لذلك سيتم تصميم فئة Java Bean الجديدة لتنفيذ UserOperation userOperation US = جديد userOperation () ؛ حاول {int feedback = us.regist (user) ؛ إذا (التعليق == userOperation.emailexist) {// يشير إلى أن عنوان البريد الإلكتروني موجود بالفعل request.setAttribute ("Message" ، "عنوان البريد الإلكتروني موجود بالفعل") ؛ request.getRequestDispatcher ("regist.jsp"). إلى الأمام (طلب ، استجابة) ؛ } آخر إذا (التعليق == userOperation.userNameExist) {// يشير إلى أن اسم المستخدم موجود بالفعل request.setAttribute ("message" ، "اسم المستخدم موجود بالفعل") ؛ request.getRequestDispatcher ("regist.jsp"). إلى الأمام (طلب ، استجابة) ؛ } آخر {// يشير إلى أن التسجيل ناجح ويقفز إلى صفحة تسجيل الدخول. لاستخدام إعادة توجيه الاستجابة. }} catch (استثناء e) {E.PrintStackTrace () ؛ رمي new RunTimeException ("إضافة فشل") ؛ }} public void dopost (httpservletrequest request ، httpservletresponse) يلقي servleTexception ، ioException {doget (request ، response) ؛ }}CheckImageservlet Class
حزمة com.vs2022.controller ؛ استيراد java.io.ioException ؛ استيراد javax.servlet.servletexception ؛ استيراد javax.servlet.http.httpservlet ؛ استيراد javax.servlet.http.httpservletrequest ؛ استيراد javax.servlet.http.httpservletresponse ؛ استيراد com.vs2022.model.CheckCode ؛ فئة عامة checkImageservlet يمتد httpservlet استجابة. استجابة. استجابة. استجابة. عرض int = 40 ؛ ارتفاع int = 30 ؛ // إنشاء كائن مجهول من رمز التحقق وإنشاء رمز التحقق الجديد checkode (). getCode (العرض ، الارتفاع ، الطلب ، الاستجابة) ؛ } public void dopost (httpservletrequest request ، httpservletresponse) يلقي servletexception ، ioException {doget (request ، response) ؛ }} تحديد فصول الأدوات
فئة DBUTIL
package com.vs2022.Utils ؛ import java.sql.*؛ استيراد com.vs2022.model.user ؛ الطبقة العامة dbutil {boolean binited = false ؛ // تحميل برنامج التشغيل public void initjdbc () يلقي classnotfoundException {// تحميل mysql jdbc driver. binited = صحيح ؛ System.out.println ("Success Loading MySQL Driver!") ؛ } الاتصال العام getConnection () يلقي classnotfoundException ، sqlexception {if (! binited) {initjdbc () ؛ } // عنوان URL للاتصال هو JDBC: MySQL // اسم عنوان/قاعدة البيانات // المعلمتين التاليتين هما تسجيل الدخول إلى اسم المستخدم وكلمة المرور conner conn = drivermanager.getConnection ("jdbc: mysql: // localhost: 3306/database" ، "username" ، "password") ؛ إرجاع كون ؛ } loginsuccess boolean العامة (اسم المستخدم سلسلة ، كلمة مرور) {boolean returnValue = false ؛ String SQL = "SELECT * من المستخدم حيث اسم المستخدم =؟ وكلمة المرور =؟" ؛ اتصال conn = null ؛ أعدت PS = NULL ؛ int i = 0 ؛ حاول {conn = getConnection () ؛ ps = conn.preparestatement (SQL) ؛ Ps.SetString (1 ، اسم المستخدم) ؛ Ps.SetString (2 ، كلمة المرور) ؛ resultset rs = ps.executequery () ؛ if (rs.next ()) {returnValue = true ؛ }} catch (classnotfoundException e) {e.printStackTrace () ؛ } catch (sqlexception e) {E.PrintStackTrace () ؛ } إرجاع returnvalue ؛ } public boolean updateUser (مستخدم المستخدم) {boolean flag = false ؛ int i = 0 ؛ اتصال conn = null ؛ أعدت PS = NULL ؛ String sql = "insert في المستخدم (اسم المستخدم ، كلمة المرور ، اللقب ، البريد الإلكتروني) قيم (؟ ،؟ ،؟)" ؛ حاول {conn = getConnection () ؛ ps = conn.preparestatement (SQL) ؛ ps.SetString (1 ، user.getUserName ()) ؛ // اضبط قيمة العنصر النائب. يبدأ ترتيب العنصر النائب من 1. المعلمة الأولى هي موضع العنصر النائب ، والمعلمة الثانية هي قيمة العنصر النائب. ps.SetString (2 ، user.getPassword ()) ؛ ps.SetString (3 ، user.getNickName ()) ؛ ps.SetString (4 ، user.getemail ()) ؛ i = ps.executeupdate () ؛ if (i> 0) {flag = true ؛ }} catch (classnotfoundException e) {e.printStackTrace () ؛ } catch (sqlexception e) {E.PrintStackTrace () ؛ } العلم الإرجاع ؛ } اسم serchusername boolean العام (سلسلة المستخدم) {boolean returnValue = false ؛ String SQL = "SELECT * من المستخدم حيث اسم المستخدم =؟" ؛ اتصال conn = null ؛ أعدت PS = NULL ؛ حاول {conn = getConnection () ؛ ps = conn.preparestatement (SQL) ؛ Ps.SetString (1 ، اسم المستخدم) ؛ resultset rs = ps.executequery () ؛ if (rs.next ()) {returnValue = true ؛ }} catch (classnotfoundException e) {e.printStackTrace () ؛ } catch (sqlexception e) {E.PrintStackTrace () ؛ } إرجاع returnvalue ؛ } serchemail boolean العامة (سلسلة البريد الإلكتروني) {boolean returnValue = false ؛ String SQL = "SELECT * من المستخدم أين البريد الإلكتروني =؟" ؛ اتصال conn = null ؛ أعدت PS = NULL ؛ int i = 0 ؛ حاول {conn = getConnection () ؛ ps = conn.preparestatement (SQL) ؛ Ps.SetString (1 ، البريد الإلكتروني) ؛ resultset rs = ps.executequery () ؛ if (rs.next ()) {returnValue = true ؛ }} catch (classnotfoundException e) {e.printStackTrace () ؛ } catch (sqlexception e) {E.PrintStackTrace () ؛ } إرجاع returnvalue ؛ }}