El diagrama de estructura MVC implementado con Java Web es el siguiente, donde la parte del controlador se implementa usando Servlet, la parte del modelo se implementa usando Javabean y la mayoría de las vistas se implementan utilizando páginas JSP.
Base ideológica
El principio de funcionamiento de la estructura de dos capas de JSP+Javabean debe ser relativamente familiar y fácil de entender.
Sin embargo, una cosa debe estar clara es que el usuario envía una solicitud de página web a través del navegador. Después de que llega esta solicitud al servidor, la página web correspondiente se encuentra en el lado del servidor. Si es la primera solicitud (la segunda vez no se explica y ejecuta), para el JSP, es necesario generar un servlet y luego ejecutar el servlet a través del motor del servlet, incrustar el resultado de llamar a Javabean a la página y devolverlo al navegador del usuario.
La esencia de la estructura de tres capas de JSP+Javabean+Servlet es que hay un controlador adicional: Servlet para distribuir solicitudes de navegador del cliente. Será de gran ayuda comprender el papel de un servlet que actúa como un controlador como preprocesamiento de la solicitud del cliente. La relación correspondiente entre las solicitudes de usuario y los servletos específicos se puede encontrar a través del archivo de configuración web.xml. Cada servlet tiene un objeto de servlet específico correspondiente a él, por lo que el que maneja las solicitudes de los usuarios es un objeto de servlet heredado de httpservlet.
!-JSPC Servlet Mapeing Start-Servlet Servlet-Namems1/Servlet-Name Servlet-Classnews.firstaction/Servlet-Class/Servlet Servlet Servlet-Namems2/Servlet-Name Servlet-Classnews1/Servlet-Class/Servlet!-JSPC Servlet Mappes Fin-Servlet-Maping Servlet-Namems1/Servlet-NAPET-NAPET URL-Pattern/NewsMain/URL-Pattern/Servlet-Maping Servlet-Maping Servlet-Namems2/Servlet-Name URL-Pattern/NewsDetail/URL-Pattern/Servlet-Maping
Como se muestra arriba, una sección de configuración de un servlet extraído de Web.xml. La primera parte se usa principalmente para configurar el servlet para estar asociado con el objeto Servlet específico. La segunda parte se usa principalmente para configurar qué servlet es procesado por la solicitud. La asociación del nombre del servlet está asociada con el objeto de procesamiento de servlet específico. Por ejemplo, el Servlet MS1 procesa la solicitud enviada por el navegador del cliente desde /NewsMain. La correspondiente Serlet Object News.Firstaction, es decir, /newsmain-ms1-news.firstaction, que es el significado del archivo de configuración. Ahora que entiendo que la solicitud de usuario/periódico será procesada por objetos de la clase de noticias. Por ejemplo, la siguiente es una implementación de FirstAction.
Public Final Clase FirstAction extiende httpservlet {Service void protegido (httpservletRequest req, httpservletResponse resp) lanza ServletException, ioexception {db db = new db (); Httpsession session = req.getSession (); Pruebe {session.setAttribute (constants.news_list_key, News .SearchNewStitle (db)); } catch (Exception e) {E.PrintStackTrace (); } db.close (); Cadena Target = "/p43_news/newsmain.jsp"; resp.sendedirect (objetivo); }} A través de esta implementación, podemos ver que cuando el servidor recibe una solicitud de cliente para realizar noticias. De esta manera, el valor correspondiente almacenado en la sesión se puede obtener a través de la función Session. GetTribute en Newsmain.jsp.
Mirando hacia atrás, es fácil ver que el principio de funcionamiento de JSP+Javabean es diferente al de JSP+Javabean+Servlet. La estructura de dos capas debe colocar el preprocesamiento en JSP, por ejemplo, News.SearchNewStitle (DB), y la estructura de tres capas primero realiza el preprocesamiento en el servlet, y luego es equivalente a devolver este resultado de procesamiento a JSP a través de la sesión, por lo que JSP presta más atención a la visualización de la interfaz.
Requisitos del módulo de registro de inicio de sesión
1 registrarse
1.1 Formulario de registro del usuario (nombre de usuario, contraseña, correo electrónico, apodo, código de verificación)
1.2 Enviar registro: verificación a (nombre de usuario, contraseña, correo electrónico, apodo, código de verificación).
1.2.1 El nombre de usuario, la contraseña, el correo electrónico y el apodo se completan en el navegador del cliente y se implementan a través de JS.
1.2.2 El código de verificación debe completarse en el programa del lado del servidor.
2. Si se aprueba la verificación del formulario de registro, entonces se juzgará la lógica comercial.
2.1 Si el usuario ya existe, dígale al usuario el mensaje de error.
2.2 Si la dirección de correo electrónico ya existe, dígale al usuario el mensaje de error.
2.3 Si no existe ninguno, proceda al paso 3.
3. Guarde la información del usuario en la base de datos
4. Regístrese con éxito, salte a la página de inicio de sesión
5. Inicie sesión
5.1 Enviar información de inicio de sesión del usuario a los antecedentes para la verificación
5.2 Si la verificación es exitosa, salta a la página de inicio
5.3 Si el salto falla, salte a la página de inicio de sesión y solicite un mensaje de error.
Estructura del directorio de proyectos
El código fuente del proyecto se divide en cuatro archivos de paquetes, que se utilizan para acceder a modelos, vistas, controladores y clases de herramientas. Los archivos específicos son los siguientes:
Para la vista, definimos tres páginas JSP de la siguiente manera:
Defina la vista
Login.jsp página
<%@ page lenguaje = "java" contentType = "text/html; charset = utf-8" PageEncoding = "utf-8"%> <! DocType html public "-// w3c // dtd html 4.01 transición // en" "http://www.w3.org/tr/html4/loos.dttd <html> <fead> <meta http-equiv = "content-type" content = "text/html; charset = utf-8"> <title> forma de inicio de sesión </title> </head> <body> <font color = "rojo"> $ {mensaje} </font> <a href = "regist.jsp"> registrar una nueva cuenta </a> <forma> <form Action = "$ {PageContext.Request.ContextPath}/Login" Method = "Post"> UserName: <input type = "text" name = "username"> <br/> contraseña: <input type = "contraseña" name = "contraseña"> <br/> <input type = "Envíe" valor = "login"> </form> </body> </html>página index.jsp
<%@ page lenguaje = "java" contentType = "text/html; charset = utf-8" PageEncoding = "utf-8"%> <%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c"%> < 4.01 Transitional // en "" http://www.w3.org/tr/html4/loose.dtd "> <html> <cead> <meta http-equiv =" content-type "content =" text/html; color = "rojo"> $ {mensaje} </font> <% if (request.getSession (). getAttribute ("username") == null) {Response.sendedirect ("Login.jsp"); } else { %> <font color = "rojo"> "bienvenido:" < %= request.getSession (). getAttribute ("username"). toString () %> </font> < %} %> </body> </html>Regist.jsp página
<%@ page lenguaje = "java" contentType = "text/html; charset = utf-8" PageEncoding = "utf-8"%> <! DocType html public "-// w3c // dtd html 4.01 transición // en" "http://www.w3.org/tr/html4/loos.dttd <html> <fead> <meta http-equiv = "content-type" content = "text/html; charset = utf-8"> <title> formulario registrado de usuario </title> <script type = "text/javaScript"> función cambieMage () {document.getEgelementById ("Image"). }/CheckImage? " + new Date (). if (username == "") {alerta ("El nombre de usuario no puede estar vacío"); devolver falso; } var contraseña = document.getElementById ("contraseña"). valor; if (contraseña == "") {alerta ("contraseña no puede estar vacía"); devolver falso; } var repassword = document.getElementById ("repassword"). valor; if (contraseña! = repassword) {alert ("la contraseña debe ser consistente"); devolver falso; } var Nnopname = document.getElementById ("Nickname"). Value; if (Nickname == "") {Alert ("Nipkname no puede estar vacío"); devolver falso; } // ^// s*// w+(?: //. {0,1} [// w-]+)*@[a-za-z0-9]+(?: [-.] [a-za-z0-9]+)*//. [a-za-z]+// s*$ var correos electrónicos = document.getEmementbyid ("correo electrónico"). Valor; if (correo electrónico.match ("^// s*// w+(?: //. {0,1} [// w-]+)*@[a-za-z0-9]+(?: [-.] [a-la-z0-9]+)*//. [a-z-z]+// s*$") ==) {alerta de correo electrónico está incorrecto "); devolver falso; }} </script> </head> <body> <h3> Tabla de registro del usuario </h3> <font color = "rojo"> $ {message} </font> <form action = "$ {pageContext.request.contextpath}/regist" onsubMit = "return ValidateForm ()"; ";"; ";;;;;; método = "post"> <topla> <tr> <tr> <td> nombre de usuario </td> <td> <input type = "text" name = "username" id = "username1" v> </td> </tr> <tr> <tr> <td> contraseña </td> <td> <trye type de entrada = "contraseña" name = "contraseña" Id = "contraseña"> </td> </tr> <tr> <tr> contraseña </td> <td> <input type = "contraseña" name = "repassword" id = "repassword"> </td> </tr> <tr> <tr> <td> apodo </td> <td> <input type = "text" name = "nickname" id = "nickname"> </td> </tr> <tr> <tr> <tr> name = "Correo electrónico" id = "correo electrónico"> </td> </tr> <tr> <td> Código de verificación </td> <td> <input type = "text" name = "checkcode"> <img src = "$ {pageContext.request.contextPath}/checkimage" style = "cursor: pointer;" "" id = "Image" onClick = "ChangeImage ();"> </td> </tr> <tr> <td> </td> <td> <input type = "enviar" valor = "registrado"> </td> </tr> </table> </form> </body> </html>> Definir el modelo
Modelo de usuario:
paquete com.vs2022.model; usuario de clase pública {Nombre de usuario de cadena privada; contraseña de cadena privada; apodo de cadena privada; correo electrónico de cadena privada; // ALT+ SHFT+ S // Aparece un cuadro de diálogo para sobrescribir el método de sobrescribencia. public String getUsername () {return UserName; } public void setUsername (String UserName) {this.Username = username; } public String getPassword () {return Password; } public void setPassword (String Password) {this.password = contraseña; } public String getNickName () {return Npokname; } public void setNickName (String Nickname) {this.nickName = Nickname; } public String getEmail () {return email; } public void setEmail (correo electrónico de cadena) {this.email = correo electrónico; }}Modelo de operación de usuario
paquete com.vs2022.model; import com.vs2022.utils.dbutil; Public Class UserOperation {public final static int usernameExist = 1; Public final static int oxagexist = 2; Público Final Final Static Int Success = 3; Public final estática int fail = 4; public int Registration (usuario de usuario) {dButil db = new dButil (); if (db.serchusername (user.getUsername ())) {// indica que el nombre de usuario ya existe return usernameExist; } if (db.serchemail (user.getEmail ())) {// Significa que la dirección de correo electrónico ya existe. Devolver emailexist; } // Si camina aquí, significa que el nombre de usuario de la dirección de correo electrónico no se almacena, así que déjelo registrarse. Agregar a la base de datos db.UpdateUser (usuario); devolver el éxito; } public int login (usuario de usuario) {dButil db = new dButil (); if (db.loginsuccess (user.getUsername (), user.getPassword ())) {// Significa que se encuentran el nombre de usuario y la contraseña. El éxito de retorno es correcto; } return fail; }} Modelo de código de control
paquete com.vs2022.model; import java.awt.color; import java.awt.font; import java.awt.graphics; import java.awt.image.bufferedImage; import java.io.ioException; import java.io.outputstream; import java.util.hashtable; import javax.imageio.imageio; import javax.servlet.servletException; import 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 width, int altura, httpservletRequest solicitud, respuesta httpservletreSponse) arroja servletException, ioexception {// crea una imagen en memoria bufferedimage imagen = nueva buffedimage (ancho, altura, bufferedimage.type_int_rgb); Gráficos g = image.getgraphics (); // Crear objeto gráfico, su función es equivalente al pincel g.setColor (color.getColor ("f8f8f8")); G.Fillrect (0, 0, ancho, altura); // dibujar la fuente de fondo mfont = nueva fuente ("kaiti", font.bold, 16); // Definir el estilo de fuente G.SetFont (MFONT); // Establecer la fuente G.SetColor (color.red); // Generar numerosa aleatoria cadena rans = getRandomString (); // Escriba el número aleatorio en la sesión Httpsession Session = request.getSession (); session.SetAttribute ("check", RANS); // Escribir número aleatorio a la imagen G.DrawString (Rans, 5, 20); // Imagen efectiva G.Dispose (); // salida Image ImageIO.Write (Imagen, "JPEG", Response.getOutputStream ());}} Defina el controlador
Clase LoginServlet
paquete com.vs2022.controller; import java.io.ioException; import java.io.printwriter; import javax.servlet.servletException; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletRequest; import javax.servlet.http.httpservletResponse; import com.vs2022.model.user.tplet.htp.httpservletresponse; import com.vs2022.model.user.tplet.htp.httpservletResponse; import com.vs2022.model.user.ttp; com.vs2022.model.userOperation; public class LoginServlet extiende httpservlet {public void doget (httpservletRequest request, httpServletResponse respuesta) lanza servletException, ioException {// lógica lógica username = request.getParameter ("userneo"); Cadena contraseña = request.getParameter ("contraseña"); Usuario user = nuevo usuario (); user.setUsername (nombre de usuario); user.setPassword (contraseña); // Llame a la función de la función comercial Javabean para implementar la lógica comercial específica de la operación de usuarios de inicio de sesión US = new UserOperation (); // Valor de retorno? int i = us.login (usuario); if (i == 4) {// Indica que el inicio de sesión falló, el nombre de usuario o la contraseña era incorrecto request.setAttribute ("mensaje", "nombre de usuario o contraseña era incorrecto"); request.getRequestDIsPatcher ("Login.jsp"). Reenviar (solicitud, respuesta); } else {// Iniciar sesión con éxito, salte a la página de inicio del sitio web, use redirección // Guardar el nombre de usuario en el dominio de la sesión. respuesta.sendedirect ("index.jsp"); //request.getRequestDispatcher("Index.jsp").Forward(Rrequest, respuesta); }} public void dopost (httpservletRequest solicitud, respuesta httpservletResponse) arroja servletException, ioexception {doget (solicitud, respuesta); }}Clase RegistServlet
paquete com.vs2022.controller; import java.io.ioException; import javax.servlet.servletException; import javax.servlet.http.httpservlet; import 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; la clase pública registservlet extiende httpservlet {public veget (hetget (hetget (hetget (hetget ( HttpServletResponse Respuesta) lanza ServletException, ioException {// Resuelve la solicitud de código confusión. // verificación completa del código de verificación String checkcode = request.getParameter ("checkcode"); String check_code_session = (string) request.getSession (). GetAttribute ("check"); if (checkcode == null ||! checkcode.equals (check_code_session)) {// indica que el código de verificación se ingresa incorrectamente request.setAttribute ("Mensaje", "El código de verificación incorrecto se ingresa incorrectamente"); request.getRequestDIsPatcher ("regist.jsp"). reenviar (solicitud, respuesta); devolver; } // Si llega aquí, significa que todas las verificaciones han pasado, y la llamada implica procesar la lógica comercial. Usuario user = nuevo usuario (); // Los beanutils completan la encapsulación de los datos en un objeto Java Bean, apache, una implementación de JAR de código abierto de la base. Pruebe {// Prerrequisito: el nombre de campo del Javabean debe ser consistente con la clave del valor enviado en el formulario, de lo contrario la encapsulación no se puede completar. BeanUtils.populate (usuario, request.getParametermap ()); } catch (Exception e) {E.PrintStackTrace (); tirar nueva runtimeException ("Lo siento, los datos de encapsulación fallaron"); } // Entonces se diseñará una nueva clase de Java Bean para implementar la Lógica de Negocios de usuario de la lógica US = New UserOperation (); intente {int Feedback = us.regist (usuario); if (folny == UserOperation.EmailExist) {// Indica que la dirección de correo electrónico ya existe request.setTribute ("Mensaje", "La dirección de correo electrónico ya existe"); request.getRequestDIsPatcher ("regist.jsp"). reenviar (solicitud, respuesta); } else if (folny == UserOperation.UsernameExist) {// Indica que el nombre de usuario ya existe request.setAttribute ("mensaje", "el nombre de usuario ya existe"); request.getRequestDIsPatcher ("regist.jsp"). reenviar (solicitud, respuesta); } else {// indica que el registro es exitoso y salta a la página de inicio de sesión. Para usar la respuesta de redirección.sendedirect ("Login.jsp"); }} catch (Exception e) {E.PrintStackTrace (); tirar nueva runtimeException ("agregar fallido"); }} public void dopost (httpservletRequest solicitud, respuesta httpservletResponse) arroja servletException, ioexception {doget (solicitud, respuesta); }}Clase CheckImageServlet
paquete com.vs2022.controller; import java.io.ioException; import javax.servlet.servletException; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletRequest; import javax.servlet.http.httpServletResponse; import com.vs2022.model.checkcode; public class CheckImageServlet extiende httpservlet {public void doget (httpservletRequest solicitud, httpServletResponse respuesta) droga servletException, ioexception {// desesable cache, visitan esta página, visitan este tiempo, visitan esta página, visitan esta página, visitan esta página, visitan esta página, visitan esta página, visitan este tiempo, visitan esta página, visitan esta página, visitan esta página, visitan este tiempo, visitan esta página, visitan esta página, visitan esta página, visiten esta página. respuesta.setheader ("Pragma", "No-Cache"); Respuesta.setheader ("Cache-Control", "No-Cache"); respuesta.setDateHeader ("expiras", 0); respuesta.setContentType ("Image/jpeg"); int ancho = 40; int altura = 30; // Genere el objeto anónimo del código de verificación y genere el código de verificación nuevo CheckCode (). GetCode (ancho, altura, solicitud, respuesta); } public void dopost (httpservletRequest solicitud, respuesta httpservletreSponse) lanza ServletException, ioexception {doget (solicitud, respuesta); }} Definir clases de herramientas
Clase dbutil
paquete com.vs2022.utils; import java.sql.*; import com.vs2022.model.user; public class dButil {boolean binited = false; // Cargar controlador public void initjdbc () lanza ClassNotFoundException {// cargar mysql jdbc controlador class.forname ("com.mysql.jdbc.driver"); binited = verdadero; System.out.println ("¡éxito Cargando el controlador MySQL!"); } Public Connection getConnection () lanza ClassNotFoundException, sqLException {if (! binited) {initJDBC (); } // La URL de conexión es JDBC: MySQL // Servidor Dirección/Nombre de la base de datos // Los siguientes dos parámetros son el nombre de usuario y la contraseña Connection conn = Drivermanager.getConnection ("jdbc: mysql: // localhost: 3306/dataBase", "userName", "contraseña"); devolver Conn; } public boolean loginsuccess (String UserName, String Password) {boolean returnValue = false; String sql = "Seleccionar * del usuario donde username =? Y contraseña =?"; Conexión conn = nulo; Preparado PS = NULL; int i = 0; intente {conn = getConnection (); ps = conn.preparestatement (SQL); Ps.SetString (1, nombre de usuario); Ps.Setstring (2, contraseña); ResultSet rs = Ps.ExecuteQuery (); if (rs.next ()) {returnValue = true; }} Catch (ClassNotFoundException e) {E.PrintStackTrace (); } Catch (Sqlexception e) {E.PrintStackTrace (); } return returnValue; } public Boolean UpdateUser (usuario de usuario) {boolean flag = false; int i = 0; Conexión conn = nulo; Preparado PS = NULL; Cadena sql = "inserte en el usuario (nombre de usuario, contraseña, apodo, correo electrónico) valores (?,?,?,?)"; intente {conn = getConnection (); ps = conn.preparestatement (SQL); Ps.SetString (1, user.getUsername ()); // Establezca el valor para el marcador de posición. La orden del marcador de posición comienza desde 1. El primer parámetro es la posición del marcador de posición, y el segundo parámetro es el valor del marcador de posición. 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 (); } Bandera de retorno; } public boolean Sergchusername (String UserName) {boolean returnValue = false; Cadena sql = "Seleccionar * de usuario donde username =?"; Conexión conn = nulo; Preparado PS = NULL; intente {conn = getConnection (); ps = conn.preparestatement (SQL); Ps.SetString (1, nombre de usuario); ResultSet rs = Ps.ExecuteQuery (); if (rs.next ()) {returnValue = true; }} Catch (ClassNotFoundException e) {E.PrintStackTrace (); } Catch (Sqlexception e) {E.PrintStackTrace (); } return returnValue; } public boolean Servchemail (correo electrónico de cadena) {boolean returnValue = false; String sql = "Seleccionar * de usuario donde correo electrónico =?"; Conexión conn = nulo; Preparado PS = NULL; int i = 0; intente {conn = getConnection (); ps = conn.preparestatement (SQL); Ps.SetString (1, correo electrónico); ResultSet rs = Ps.ExecuteQuery (); if (rs.next ()) {returnValue = true; }} Catch (ClassNotFoundException e) {E.PrintStackTrace (); } Catch (Sqlexception e) {E.PrintStackTrace (); } return returnValue; }}