Le diagramme de structure MVC implémenté à l'aide de Java Web est le suivant, où la pièce de contrôleur est implémentée à l'aide du servlet, la partie du modèle est implémentée à l'aide de JavaBean, et la plupart des vues sont implémentées à l'aide de pages JSP.
Fondation idéologique
Le principe de travail de la structure à deux couches de JSP + JavaBean devrait être relativement familier et facile à comprendre.
Cependant, une chose doit être claire est que l'utilisateur envoie une demande de page Web via le navigateur. Une fois cette demande arrivée sur le serveur, la page Web correspondante est trouvée du côté du serveur. S'il s'agit de la première demande (la deuxième fois n'est pas expliquée et exécutée), pour le JSP, il est nécessaire de générer un servlet, puis d'exécuter le servlet via le moteur de servlet, d'incorporer le résultat de l'appel JavaBean dans la page et de le retourner au navigateur de l'utilisateur.
L'essence de la structure à trois couches du servlet JSP + JAVABEAN + est qu'il existe un contrôleur supplémentaire: Servlet pour distribuer les demandes du navigateur client. Il sera d'une grande aide pour comprendre le rôle d'un servlet qui agit comme un contrôleur comme prétraitement de la demande du client. La relation correspondante entre les demandes utilisateur et les servlets spécifiques peut être trouvée via le fichier de configuration web.xml. Chaque servlet a un objet de servlet spécifique qui lui correspond, donc celui qui gère les demandes de l'utilisateur est un objet de servlet hérité de Httpservlet.
! - JSPC servlet Mappings Start - Servlet Servlet-namems1 / Servlet-Name Servlet-ClassNews.Firstaction / Servlet-Class / Servlet Servlet Namems2 / Servlet-Name Servlet-Classnews.Detailaction / Servlet-Class / Servlet! - JSPC Servlet Mapping End - Servlet-mapping-mapp URL-Pattern / Newsmain / URL-Pattern / Servlet Mapping Servlet Mapping Servlet-Namems2 / Servlet-Name-Pattern / Newsdetail / URL-Pattern / Servlet Mapping
Comme indiqué ci-dessus, une section du servlet de configuration extrant à partir de web.xml. La première partie est principalement utilisée pour configurer le servlet pour être associé à l'objet de servlet spécifique. La deuxième partie est principalement utilisée pour configurer le servlet traité par la demande. L'association du nom du servlet est associée à l'objet de traitement du servlet spécifique. Par exemple, la demande envoyée par le navigateur client de / newsmain est traitée par le servlet MS1. L'objet serlet correspondant news.firstaction, c'est-à-dire, /newsmain-ms1-news.firstaction, qui est la signification du fichier de configuration. Maintenant que je comprends que la demande utilisateur / newsmain sera traitée par des objets de la classe News.Firstaction, donc pour comprendre le programme, vous devez comprendre quelle est la fonction de FirstAction. Par exemple, ce qui suit est une implémentation de FirstAction.
Public Final Class FirstAction étend HttpServlet {Protected Void Service (HttpServletRequest req, httpServletResponse resp) lève ServletException, ioException {db db = new db (); HttpSession Session = req.getSession (); essayez {session.setAttribute (constants.news_list_key, news .searchNewstitle (db)); } catch (exception e) {e.printStackTrace (); } db.close (); String Target = "/p43_news/newsmain.jsp"; resp.sendRedirect (cible); }} Grâce à cette implémentation, nous pouvons voir que lorsque le serveur reçoit une demande client pour effectuer des news.searchNewstitle (DB), puis met la valeur de retour dans la session via session.setattribute, puis le transfère indirectement sur newsmain.jsp via resp.sendRedirect (Target). De cette façon, la valeur correspondante stockée dans la session peut être obtenue via la fonction Session.getAttribute dans newsmain.jsp.
Avec le recul, il est facile de voir que le principe de travail de JSP + Javabean est différent de celui de JSP + JavaBean + Servlet. La structure à deux couches doit placer le prétraitement dans JSP, par exemple, News.SearchNewstiTle (DB), et la structure à trois couches effectue d'abord le prétraitement dans le servlet, puis il équivaut à retourner ce résultat de traitement à JSP via la session, de sorte que JSP accorde plus d'attention à l'affichage de l'interface.
Exigences du module d'enregistrement de connexion
1 enregistrement
1.1 Formulaire d'enregistrement de l'utilisateur (nom d'utilisateur, mot de passe, e-mail, surnom, code de vérification)
1.2 Soumettre l'enregistrement: vérification à (nom d'utilisateur, mot de passe, e-mail, surnom, code de vérification).
1.2.1 Le nom d'utilisateur, le mot de passe, l'e-mail et le surnom sont terminés dans le navigateur client et implémentés via JS.
1.2.2 Le code de vérification doit être terminé dans le programme côté serveur.
2. Si la vérification du formulaire d'enregistrement est adoptée, la logique commerciale sera jugée.
2.1 Si l'utilisateur existe déjà, dites à l'utilisateur le message d'erreur.
2.2 Si l'adresse e-mail existe déjà, dites à l'utilisateur le message d'erreur.
2.3 Si aucune n'existe, passez à l'étape 3.
3. Enregistrer les informations de l'utilisateur dans la base de données
4. Inscrivez-vous avec succès, passez à la page de connexion
5. Connectez-vous
5.1 Envoyez les informations de connexion de l'utilisateur à l'arrière-plan pour la vérification
5.2 Si la vérification est réussie, passez à la page d'accueil
5.3 Si le saut échoue, passez à la page de connexion et demandez un message d'erreur.
Structure du répertoire de projet
Le code source du projet est divisé en quatre fichiers de package, qui sont utilisés pour accéder aux modèles, vues, contrôleurs et classes d'outils. Les fichiers spécifiques sont les suivants:
Pour la vue, nous définissons trois pages JSP comme suit:
Définir la vue
page login.jsp
<% @ Page Language = "Java" ContentType = "Text / Html; charSet = UTF-8" Pageencoding = "UTF-8"%> <! Doctype HTML PUBLIC "- // W3C // DTD HTML 4.01 Transitional // En" "http://www.w3.org/tr/html4/loose" <html> <éad- head> <meta http-equiv = "content-type" contenu = "text / html; charset = utf-8"> <ititle> formulaire de connexion </title> </ head> <body> <font color = "red"> $ {message} </font> <a href = "regist.jsp"> Register un nouveau compte </a> action = "$ {pageConText.Request.ContextPath} / Login" Method = "Post"> Username: <Input Type = "Text" Name = "Username"> <br/> Password: <Input Type = "Password" Name = "Password"> <br/> <Input Type = "soumed" Value = "Login"> </ form> </body> </html>page index.jsp
<% @ Page Language = "Java" ContentType = "Text / Html; Charset = UTF-8" Pageencoding = "UTF-8"%> <% @ Taglib Uri = "http://java.sun.com/jsp/jstl/core" Prefix = "C"%> <! DocType Html Guber 4.01 Transitional // en "" http://www.w3.org/tr/html4/loose.dtd "> <html> <adref> <meta http-equiv =" contenu-type "title d'insertion ici </ title> color = "red"> $ {message} </font> <% if (request.getSession (). getAttribute ("username") == null) {réponse.sendRedirect ("login.jsp"); } else {%> <font color = "red"> "bienvenue:" <% = request.getSession (). getAtTribute ("username"). toString ()%> </font> <%}%> </ body> </html>Page Regist.jsp
<% @ Page Language = "Java" ContentType = "Text / Html; charSet = UTF-8" Pageencoding = "UTF-8"%> <! Doctype HTML PUBLIC "- // W3C // DTD HTML 4.01 Transitional // En" "http://www.w3.org/tr/html4/loose" <html> <éadfr> <méta http-equiv = "contenu-type" contenu = "text / html; charset = utf-8"> <ititle> formulaire enregistré utilisateur </ title> <script type = "text / javascrip } / CheckImage? " + new Date (). getTime ()} function valideform () {// Vérifier le nom d'utilisateur, le mot de passe, le courriel, le surnom var userName = document.getElementById ("username"). valeur; if (username == "") {alert ("nom d'utilisateur ne peut pas être vide"); retourne false; } var mot de passe = document.getElementById ("mot de passe"). valeur; if (mot de passe == "") {alert ("mot de passe ne peut pas être vide"); retourne false; } var repassword = document.getElementById ("repassword"). valeur; if (mot de passe! = repassword) {alert ("mot de passe doit être cohérent"); retourne false; } var naunom = document.getElementById ("surnom"). valeur; if (nontename == "") {alert ("Nonom ne peut pas être vide"); retourne false; } // ^ // s * // w + (?: //. {0,1} [// w-] +) * @ [a-za-z0-9] + (?: [-.] [a-za-z0-9] +) * //. if (email.match ("^ // s * // w + (?: //. {0,1} [// w-] +) * @ [a-za-z0-9] + (?: [-.] [a-za-z0-9] +) * //. retourne false; }} </ script> </ head> <body> <h3> Tableau de l'enregistrement des utilisateurs </h3> <font color = "red"> $ {message} </font> <form action = "$ {pageContext.Request.ContextPath} / Regist" onSubmit = "return valideform ();" Method = "Post"> <Table> <Tr> <Td> Nom d'utilisateur </td> <td> <Input Type = "Text" name = "Username" ID = "Username1" V> </Td> </ Tr> <Tr> <Td> Mot de passe </ TD> <TD> <PUT TYPE = "Password" Name = "Passue" ID = "Mot de passe"> </td> mot de passe </td> <td> <entrée type = "mot de passe" name = "repassword" id = "repassword"> </td> </ tr> <tr> <td> nausément </td> <td> <input type = "text" name = "nickname" id = "nickname"> </td> </tr> <tr> <td> e-mail </ td> name = "e-mail" id = "e-mail"> </td> </tr> <tr> <td> Code de vérification </td> <td> <input type = "text" name = "checkcode"> <img src = "$ {pageContext.Request.ContextPath} / CheckImage" style = "curseur: Pointer;" id = "Image" onClick = "ChangeImage ();"> </td> </tr> <tr> <td> </td> <td> <input type = "soumed" value = "Enregistrement"> </td> </tr> </s table> </ form> </ body> </html> Définir le modèle
Modèle d'utilisateur:
package com.vs2022.model; public class user {private String username; mot de passe de chaîne privé; surnom de cordes privées; e-mail de chaîne privée; // alt + shft + s // Une boîte de dialogue pour la méthode d'écrasement apparaît. public String getUserName () {return username; } public void setUsername (String username) {this.userName = username; } public String getPassword () {return mot de passe; } public void setPassword (String Motword) {this.password = mot de passe; } public String getNickName () {return newame; } public void setNickName (String Nelname) {this.nickName = Nontes; } public String getEmail () {return e-mail; } public void setEmail (chaîne e-mail) {this.email = e-mail; }}Modèle d'utilisation
package com.vs2022.model; import com.vs2022.utils.dbutil; public class userOperation {public final static int userNameExist = 1; public final static int e-mailExist = 2; Public final static int succès = 3; public final static int échoue = 4; Public int Registration (utilisateur utilisateur) {dButil db = new DButil (); if (db.serchusername (user.getUserName ())) {// indique que le nom d'utilisateur existe déjà de retour userNameExist; } if (db.serChemail (user.getEmail ())) {// Cela signifie que l'adresse e-mail existe déjà. Retourner EMAILexist; } // Si vous marchez ici, cela signifie que le nom d'utilisateur de l'adresse e-mail n'est pas stocké, alors laissez-le s'inscrire. Ajouter à la base de données db.updateUser (utilisateur); retourner le succès; } public int ligin (utilisateur utilisateur) {dButil db = new dButil (); if (db.loginsuccess (user.getUserName (), user.getPassword ())) {// Cela signifie que le nom d'utilisateur et le mot de passe sont corrects ont été trouvés. Retourner le succès; } return fail; }} Modèle de code de contrôle
package com.vs2022.model; import java.awt.color; Importer java.awt.font; import java.awt.graphics; Importer java.awt.image.bufferedImage; Importer java.io.ioException; import java.io.outputStream; import java.util.hashTable; import javax.imageio.imageio; Importer javax.servlet.servletException; Importer javax.servlet.http.httpservletRequest; import javax.servlet.http.httpservletResponse; import javax.servlet.http.httpSession; public class checkcode {private String getrandomString () {int rannum = (int) (math.random () * 9000) + 1000; return rannum + "";} public void getcode (int largeth, int hauteur, httpservletRequest request, httpservletResponse) lève ServletException, ioException {// Créer une image dans la mémoire buffredImage = new BufferedImage (largeur, hauteur, buffredimage.type_int_rgb); Graphiques g = image.getGraphics (); // Créer un objet graphique, sa fonction est équivalente au pinceau g.setColor (Color.getColor ("f8f8f8")); G.Fillrect (0, 0, largeur, hauteur); // dessine la police d'arrière-plan mfont = new Font ("kaiti", font.bold, 16); // définir le style de police g.setfont (mfont); // Définissez la police g.setColor (Color.red); // générer des chaînes de nombres aléatoires rans = getRandomString (); // Écrivez le numéro aléatoire à la session httpSession session = request.getSession (); session.setAttribute ("Check", Rans); // Écrivez un nombre aléatoire sur l'image G.Drawstring (Rans, 5, 20); // image efficace g.dispose (); // Sortie Image imageo.write (image, "jpeg", réponse.getOutputStream ());}} Définir le contrôleur
Classe de connexion
package com.vs2022.Controller; import java.io.ioException; Importer java.io.printwriter; import javax.servlet.servletException; import javax.servlet.http.httpservlet; importer javax.servlet.http.httpservletRequest; import com.vs2022.Model.user; com.vs2022.model.UserOperation; public class LoginServlet étend httpservlet {public void doget (httpservletRequest request, httpservletResponse réponse) lève ServletException, ioException {// logical string username = request.getParamètre ("username"); String mot de passe = request.getParameter ("mot de passe"); Utilisateur utilisateur = nouveau utilisateur (); user.setUsername (nom d'utilisateur); user.setpassword (mot de passe); // Appelez la classe JavaBean de la fonction commerciale pour implémenter la logique métier spécifique de la connexion userOperation us = new userOperation (); // Valeur de retour? int i = us.login (utilisateur); si (i == 4) {// il indique que la connexion a échoué, le nom d'utilisateur ou le mot de passe était incorrect request.setAttribute ("message", "le nom d'utilisateur ou le mot de passe était incorrect"); request.getRequestDispatcher ("Login.jsp"). Forward (demande, réponse); } else {// Connectez-vous avec succès, passez à la page d'accueil du site Web, utilisez Redirection // Enregistrer le nom d'utilisateur dans le domaine de session request.getSession (). setAttribute ("username", nom d'utilisateur); Response.SendRedirect ("index.jsp"); //request.getRequestDispatcher("index.jsp").Forward(request, réponse); }} public void doPost (httpsservletRequest request, httpservletResponse réponse) lève ServletException, ioException {doGet (request, réponse); }}Classe RegistServlet
package com.vs2022.Controller; import java.io.ioException; Importer javax.servlet.servletException; import javax.servlet.http.httpservlet; Importer javax.servlet.http.httpservletRequest; Import Javax.servlet.http.httpservletResponse; import com.sun.org.apache.commons.beanutils.beanutils; import com.vs2022.model.user; import com.vs2022.model.UserOperation; public class registserv. HttpServletResponse Response) lève Servlexception, ioException {// résoudre le code brouillé request.SetcharAtterencoding ("utf-8"); // Vérification complète de la chaîne de code de vérification CheckCode = request.getParameter ("CheckCode"); String Check_Code_Session = (String) request.getSession (). GetAttribute ("Check"); if (checkcode == null ||! checkcode.equals (Check_Code_Session)) {// indique que le code de vérification est incorrectement demande.setAttribute ("Message", "Le code de vérification incorrect est incorrectement"); request.getRequestDispatcher ("Regist.jsp"). Forward (demande, réponse); retour; } // Si vous arrivez ici, cela signifie que toutes les vérifications sont passées et que l'appel implique le traitement de la logique métier. Utilisateur utilisateur = nouveau utilisateur (); // Beanutils complète l'encapsulation des données dans un objet Java Bean, Apache un pot open source de la fondation de la fondation. Essayez {// Prérequis: le nom de champ de la Javabean doit être cohérent avec la clé de la valeur soumise dans le formulaire, sinon l'encapsulation ne peut pas être terminée. Beanutils.populer (utilisateur, request.getParameTermap ()); } catch (exception e) {e.printStackTrace (); lancer un nouveau RuntimeException ("Désolé, les données d'encapsulation ont échoué"); } // Ainsi, une nouvelle classe Java Bean sera conçue pour implémenter une logique métier us us = new userOperation (); essayez {int feedback = us.Regist (utilisateur); if (feedback == useroperation.emailexist) {// indique que l'adresse e-mail existe déjà request.setAttribute ("message", "l'adresse e-mail existe déjà"); request.getRequestDispatcher ("Regist.jsp"). Forward (demande, réponse); } else if (feedback == userOperation.UserNameExist) {// indique que le nom d'utilisateur existe déjà request.setAttribute ("message", "le nom d'utilisateur existe déjà"); request.getRequestDispatcher ("Regist.jsp"). Forward (demande, réponse); } else {// indique que l'enregistrement réussit et saute à la page de connexion. Pour utiliser Redirect Response.SendRedirect ("Login.jsp"); }} catch (exception e) {e.printStackTrace (); lancer un nouveau RuntimeException ("Ajouter un échec"); }} public void doPost (httpsservletRequest request, httpservletResponse réponse) lève ServletException, ioException {doGet (request, réponse); }}Classe de contrôle de contrôle
package com.vs2022.Controller; import java.io.ioException; Importer javax.servlet.servletException; import javax.servlet.http.httpservlet; Importer javax.servlet.http.httpservletRequest; import javax.servlet.http.HttpServletResponse;import com.vs2022.model.CheckCode;public class CheckImageServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //Disable cache, every time you visit this page, regenerate Response.sethEader ("Pragma", "No-Cache"); Response.sethEader ("Cache-Control", "No-cache"); réponse.setDateHeader ("expire", 0); réponse.setContentType ("Image / JPEG"); Int largeur = 40; int hauteur = 30; // générer un objet anonyme du code de vérification et générer du code de vérification nouveau Checkcode (). GetCode (largeur, hauteur, demande, réponse); } public void doPost (requête HttpServletRequest, réponse httpservletResponse) lève ServletException, ioException {doget (request, réponse); }} Définir les classes d'outils
Classe dbutil
package com.vs2022.utils; import java.sql. *; import com.vs2022.model.user; classe publique dbutil {boolean binited = false; // Charger le pilote public void initjdbc () lève classnotfoundException {// charger mysql jdbc driver class.forname ("com.mysql.jdbc.driver"); binited = true; System.out.println ("Success chargement du pilote mysql!"); } Connexion publique getConnection () lève ClassNotFoundException, sqException {if (! binited) {initJdbc (); } // L'URL de connexion est JDBC: MySQL // Adresse du serveur / Nom de la base de données // Les deux paramètres suivants sont le nom d'utilisateur de connexion et la connexion par mot de passe Conn = DriverManager.getConnection ("JDBC: MySQL: // LocalHost: 3306 / Database", "Username", "Motway"); Retourne Conn; } public booléan LoginSuccess (nom d'utilisateur de chaîne, mot de passe de chaîne) {boolean returnValue = false; String sql = "SELECT * FROM User Where Username =? Et Password =?"; Connexion conn = null; PréparedStatement PS = null; int i = 0; essayez {conn = getConnection (); ps = conn.preparestatement (SQL); ps.SetString (1, nom d'utilisateur); ps.SetString (2, mot de passe); ResultSet rs = ps.ExecuteQuery (); if (Rs.Next ()) {returnValue = true; }} catch (classNotFoundException e) {e.printStackTrace (); } catch (sqlexception e) {e.printStackTrace (); } return returnValue; } public boolean updateUser (utilisateur utilisateur) {booléen flag = false; int i = 0; Connexion conn = null; PréparedStatement PS = null; String sql = "Insérer dans l'utilisateur (nom d'utilisateur, mot de passe, surnom, e-mail) VALEURS (?,?,?)"; essayez {conn = getConnection (); ps = conn.preparestatement (SQL); ps.SetString (1, user.getUserName ()); // Définissez la valeur de l'espace réservé. L'ordre de placement commence à partir de 1. Le premier paramètre est la position de l'espace réservé, et le deuxième paramètre est la valeur de l'espace réservé. 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 (); } drapeau de retour; } public boolean serchuserName (String username) {boolean returnValue = false; String sql = "SELECT * FROM User Where Username =?"; Connexion conn = null; PréparedStatement PS = null; essayez {conn = getConnection (); ps = conn.preparestatement (SQL); ps.SetString (1, nom d'utilisateur); ResultSet rs = ps.ExecuteQuery (); if (Rs.Next ()) {returnValue = true; }} catch (classNotFoundException e) {e.printStackTrace (); } catch (sqlexception e) {e.printStackTrace (); } return returnValue; } public boolean serchemail (chaîne e-mail) {boolean returnValue = false; String SQL = "SELECT * FROM User Where Email =?"; Connexion conn = null; PréparedStatement PS = null; int i = 0; essayez {conn = getConnection (); ps = conn.preparestatement (SQL); ps.SetString (1, e-mail); ResultSet rs = ps.ExecuteQuery (); if (Rs.Next ()) {returnValue = true; }} catch (classNotFoundException e) {e.printStackTrace (); } catch (sqlexception e) {e.printStackTrace (); } return returnValue; }}