O diagrama de estrutura MVC implementado usando o Java Web é o seguinte, onde a parte do controlador é implementada usando o servlet, a parte do modelo é implementada usando o Javabean e a maioria das visualizações é implementada usando páginas JSP.
Fundação ideológica
O princípio de trabalho da estrutura de duas camadas do JSP+Javabean deve ser relativamente familiar e fácil de entender.
No entanto, uma coisa deve ficar clara é que o usuário envia uma solicitação de página da web através do navegador. Depois que essa solicitação chega ao servidor, a página da web correspondente é encontrada no lado do servidor. Se for a primeira solicitação (a segunda vez não for explicada e executada), para o JSP, é necessário gerar um servlet e executar o servlet através do mecanismo de servlet, incorpore o resultado de chamar Javabean na página e devolvê -lo ao navegador do usuário.
A essência da estrutura de três camadas do JSP+Javabean+Servlet é que existe um controlador adicional: servlet para distribuir solicitações do navegador do cliente. Será de grande ajuda entender o papel de um servlet que atua como um controlador como pré -processando a solicitação do cliente. O relacionamento correspondente entre solicitações de usuário e servlets específicos pode ser encontrado através do arquivo de configuração do web.xml. Cada servlet possui um objeto de servlet específico correspondente a ele; portanto, aquele que lida com as solicitações do usuário é um objeto de servlet herdado do httpServlet.
!-JSPC Servlet Mappings Início-servlet servlet-namemas1/servlet-name servlet-classnews.firstaction/servlet-class/servlet servlet-namemas2/servlet-name servlet-classapsnews.detailaction/servlet-class/servlet!-jsp servlet e servletn-mamen-mamen-namen-namen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-mamen-e-servlet. URL-Pattern/NewsMain/Url-Pattern/Servlet-mapeamento de servlet-mapeando servlet-namemas2/servlet-name url-padrão/newsdetail/url-padrão/servlet-mapping
Como mostrado acima, uma seção do servlet de configuração extraída do web.xml. A primeira parte é usada principalmente para configurar o servlet para ser associado ao objeto de servlet específico. A segunda parte é usada principalmente para configurar qual servlet é processado pela solicitação. A associação do nome do servlet está associada ao objeto de processamento de servlet específico. Por exemplo, a solicitação enviada pelo navegador do cliente do /NewsMain é processada pelo MS1 Servlet. O objeto serlet correspondente notícias.Firstaction, ou seja, /newsMain-ms1-news.firstaction, que é o significado do arquivo de configuração. Agora que entendo que a solicitação de usuário/newsmain será processada por objetos da classe Notícias.Firstaction; para entender o programa, você deve entender qual é a função da FirstAction. Por exemplo, a seguir é uma implementação da FirstAction.
A classe final pública FirstAction estende httpServlet {serviço vazio protegido (httpServletRequest req, httpServletResponse resp) lança servletexception, ioexception {db db = new db (); Session httpSession = req.getSession (); tente {session.setAttribute (constantes.news_list_key, notícias .searchNewStitle (db)); } catch (Exceção e) {e.printStackTrace (); } db.close (); String Target = "/p43_news/newsmain.jsp"; resp.SendRedirect (Target); }} Por meio dessa implementação, podemos ver que, quando o servidor recebe uma solicitação do cliente para executar o News.searchNewStitle (DB), então coloca o valor de retorno na sessão através do session.setAttribute e, em seguida, o transfere indiretamente para o Newsmain.jsp através do resp.sendRirect (Target). Dessa forma, o valor correspondente armazenado na sessão pode ser obtido através da função Session.GetAttribute no NewsMain.jsp.
Olhando para trás, é fácil ver que o princípio de funcionamento do JSP+Javabean é diferente do do JSP+Javabean+Servlet. A estrutura de duas camadas deve colocar o pré-processamento no JSP, por exemplo, News.searchNewStitle (DB), e a estrutura de três camadas primeiro executa o pré-processamento no servlet e, em seguida, é equivalente a retornar esse resultado de processamento ao JSP por meio da sessão, de modo que o JSP pague mais atenção à exibição da interface.
Requisitos do módulo de registro de login
1 registro
1.1 Formulário de registro do usuário (nome de usuário, senha, email, apelido, código de verificação)
1.2 Enviar registro: verificação para (nome de usuário, senha, email, apelido, código de verificação).
1.2.1 O nome de usuário, senha, email e apelido são concluídos no navegador do cliente e implementados através do JS.
1.2.2 O código de verificação deve ser concluído no programa do servidor.
2. Se a verificação do formulário de registro for aprovada, a lógica de negócios será julgada.
2.1 Se o usuário já existir, informe ao usuário a mensagem de erro.
2.2 Se o endereço de email já existir, informe ao usuário a mensagem de erro.
2.3 Se não existir, prossiga para a etapa 3.
3. Salve as informações do usuário no banco de dados
4. Registre -se com sucesso, pule para a página de login
5. Faça login
5.1 Envie as informações de login do usuário para o plano de fundo para verificação
5.2 Se a verificação for bem -sucedida, pule para a página inicial
5.3 Se o salto falhar, pule para a página de login e solicite uma mensagem de erro.
Estrutura do diretório do projeto
O código -fonte do projeto é dividido em quatro arquivos de pacotes, que são usados para acessar modelos, visualizações, controladores e classes de ferramentas. Os arquivos específicos são os seguintes:
Para a vista, definimos três páginas JSP da seguinte forma:
Defina a vista
Página login.jsp
<%@ página linguagem = "java" contentType = "text/html; charset = utf-8" PageEncoding = "utf-8"%> <! <html> <head> <meta http-equiv = "content-type" content = "text/html; charset = utf-8"> <title> Formulário de login </title> </head> <body> <font color = "Red"> $ {message} </font <a href) Action = "$ {PageContext.Request.ContextPath}/login" Method = "post"> Nome de usuário: <input type = "text" name = "userrname"> <br/> Senha: <input type = "senha" name = "senha"> <br/> <input = "submit"/"value =" Login ">Página Index.jsp
<%@ página linguagem = "java" contentType = "text/html; charset = utf-8" PageEncoding = "utf-8"%> <%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c"%> <! 4.01 Transição // pt "" http://www.w3.org/tr/html4/loose.dtd "> <html> <head> <meta http-equiv =" content-type "content =" text/html; color = "Red"> $ {message} </font> <% se (request.getSession (). getAttribute ("nome de usuário") == null) {Response.sendredirect ("login.jsp"); } else { %> <font color = "Red"> "Bem -vindo:" < %= request.getSession (). getAttribute ("nome de usuário").página regist.jsp
<%@ página linguagem = "java" contentType = "text/html; charset = utf-8" PageEncoding = "utf-8"%> <! <html> <head> <meta http-equiv = "content-type" content = "text/html; charset = utf-8"> <title> Formulário registrado do usuário </ititure> <script type = "text/javascript"> functionImage () {DocumentElementnExtById ("imagem". }/checkImage? " + new date (). gettime ()} function validesform () {// verifique o nome de usuário, senha, email, apelido var userName = document.getElementById ("nome de usuário"). if (nome de usuário == "") {alert ("nome de usuário não pode estar vazio"); retornar falso; } var senha = document.getElementById ("senha"). if (senha == "") {alert ("A senha não pode estar vazia"); retornar falso; } var repassword = document.getElementById ("repassword"). value; if (senha! = Repassword) {alert ("A senha deve ser consistente"); retornar falso; } var apelido = document.getElementById ("apelido"). Value; if (apelido == "") {alert ("apelido não pode estar vazio"); retornar falso; } // ^// s*// w+(?: //. {0,1} [// w-]+)*@[a-za-z0-9]+(?: [-.] [a-za-z0-9]+)*//. [a-za-z]+// s*$ varail = documenty)*//. if (email.match ("^// s*// w+(?: //. {0,1} [// w-]+)*@[a-za-z0-9]+(?: [-.] [a-za-z0-9]+)*//. retornar falso; }} </sCript> </head> <body> <h3> Tabela de registro do usuário </h3> <font color = "Red"> $ {message} </font> <formulário action = "$ {pageContext.request.ContextPath}/regist" onSubmit = "retornar validformform ();" Method = "Post"> <tabela> <tr> <td> nome de usuário </td> <td> <input type = "text" name = "userName" id = "username1" v> </td> </tr> <tr> <td> senha </td> <td> <input type = "senha" name = "" ids> "idéia" = <td> senha </td> <td> <input Type = "senha" Name = "" id> "idé" <Td> senha </td> <td> <input = "senha" name = "" id> "idé:" password</td> <td> <input type="password" name="repassword" id="repassword"> </td> </tr> <tr> <td>Nickname</td> <td> <input type="text" name="nickname" id="nickname"> </td> </tr> <tr> <td>Email</td> <td> <input type="text" name = "email" id = "email"> </td> </tr> <tr> <td> código de verificação </td> <td> <input type = "text" name = "checkcode"> <img src = "$ {PagContext.Request.ContextPath}/checkinage" style = "" id = "imagem" onclick = "changeImage ();"> </td> </tr> <tr> <td> </td> <td> <input type = "submit" value = "registro"> </td> </tr> </ table> </form> </body> </html> Defina o modelo
Modelo de usuário:
pacote com.vs2022.model; public class Usuário {private string nome de usuário; senha de sequência privada; apelido de string privada; e -mail privado de string; // alt+ shft+ s // uma caixa de diálogo para o método de sobrescrição aparece. public String getUserName () {return Username; } public void setUserName (string userName) {this.username = nome de usuário; } public string getPassword () {return senha; } public void setPassword (string senha) {this.password = senha; } public String getNickName () {return apelido; } public void setNickName (String apelido) {this.nickname = apelido; } public String getEmail () {retornar email; } public void setEmail (string email) {this.email = email; }}Modelo de UserOperation
pacote com.vs2022.model; import com.vs2022.utils.dbutil; public class Useroperation {public final static int userramexist = 1; public final static int emailExist = 2; public final static int sucem = 3; public final static int falha = 4; Public Int Registration (usuário do usuário) {dbutil db = new dbutil (); if (db.serchusername (user.getUserName ())) {// indica que o nome do usuário já existe retornar userNameExist; } if (db.serchemail (user.getEmail ())) {// significa que o endereço de email já existe. Retornar emailxist; } // Se você caminhar aqui, isso significa que o nome do endereço de email não está armazenado, então deixe -o se registrar. Adicione ao banco de dados DB.UpDateUser (Usuário); sucesso de sucesso; } public int Login (usuário do usuário) {dbutil db = new dbutil (); if (db.loginsuccess (user.getUserName (), user.getpassword ())) {// significa que o nome de usuário e a senha estão corretos foram encontrados. Sucesso de sucesso; } retornar falha; }} Modelo de código de seleção
pacote com.vs2022.model; importar java.awt.color; importar java.awt.font; importar java.awt.graphics; importar java.awt.image.bufferiMage; importar java.io.ioException; importar java.io.OutputStream; importar java.util.hashtable; importar javax.imageio.imageio; importar javax.servlet.servletexception; importar javax.servlet.http.httpServletRequest; importar javax.servlet.http.httpServletResponse; importar javax.servlet.http.httpSession; public class CheckCode {private String getRandomstring () {int rannum = (int) (math.random () * 9000) + 1000; Retornar Rannum + "";} public void getCode (int width, int altura, httpServletRequest Solicy, httpServletResponse resposta) lança servletexception, ioexception {// criar imagem na imagem bufferImage imagem = newbhowImage (largura, altura, bufferImage.Type__IntgB Gráficos g = image.getGraphics (); // Crie objeto gráfico, sua função é equivalente ao pincel g.setColor (color.getColor ("f8f8f8")); G.FillRect (0, 0, largura, altura); // desenhe a fonte de fundo mfont = new font ("kaiti", font.bold, 16); // Defina o estilo da fonte G.SetFont (MFONT); // defina a fonte G.SetColor (color.red); // gerar número aleatório string rans = getRandomstring (); // Escreva o número aleatório na sessão httpssession session = request.getSession (); session.setAttribute ("Check", RANS); // Escreva um número aleatório na imagem G.DrawString (RANS, 5, 20); // imagem eficaz g.dispose (); // Saída Image Imageio.Write (Image, "JPEG", Response.getOutputStream ());}} Defina o controlador
Classe de LogInservlet
pacote com.vs2022.Controller; importar java.io.ioException; importar java.io.printwriter; importar javax.servlet.servletexception; importar javax.servlet.http.httpServlet; import javax.servlet.http.httpServErquest; import javax.servlet.htttP.SensportRestLeSponsless; com.vs2022.model.useroperation; public class Loginservlet estende httpServlet {public void Doget (solicitação httpServletRequest, httpServletResponse resposta) lança servEtexception, ioexception {// lógico lógico lógico Username = solicitante.GeTEMeter ( String senha = request.getParameter ("senha"); Usuário do usuário = novo usuário (); user.setUserName (nome de usuário); user.setPassword (senha); // Ligue para a função de negócios Javabean Class para implementar a lógica de negócios específica do login userOperation US = new UserOperation (); // Valor de retorno? int i = nós.login (usuário); if (i == 4) {// indica que o login falhou, o nome de usuário ou a senha estava incorreto request.setAttribute ("mensagem", "nome de usuário ou senha estava incorreto"); request.getRequestDispatcher ("login.jsp"). Forward (solicitação, resposta); } else {// Faça login com sucesso, pule para a página inicial do site, use redirecionamento // Salvar o nome de usuário no domínio da sessão request.getSession (). setAttribute ("nome de usuário", nome de usuário); Response.sendRedirect ("index.jsp"); //request.getRequestDispatcher("index.jsp").forward(request, resposta); }} public void DoPost (solicitação httpServletRequest, httpServletResponse resposta) lança servletexception, ioexception {doget (solicitação, resposta); }}Classe do RegistServlet
pacote com.vs2022.Controller; importar java.io.ioException; importar javax.servlet.servletexception; importar javax.servlet.http.httpServlet; importar javax.servlet.http.httpServletRequest; importar javax.servlet.http.httpServletResponse; importação com.sun.org.apache.commons.beanutils.beanutils; importar com.vs2022.model.USTERSVENVENTES; HttpServLeTResponse Response) lança servleTexception, ioexception {// Resolva o código de código iluminado.SetcharAcTerEncoding ("UTF-8"); // Verificação completa do código de verificação string de stringcode = request.getParameter ("CheckCode"); String check_code_session = (string) request.getSession (). GetAttribute ("check"); if (checkcode == null ||! checkcode.equals (check_code_session)) {// indicam que o código de verificação é inserido incorretamente request.setAttribute ("mensagem", "o código de verificação incorreto é inserido incorretamente"); request.getRequestDispatcher ("regist.jsp"). Forward (solicitação, resposta); retornar; } // Se você chegar aqui, isso significa que todas as verificações foram aprovadas e a chamada envolve o processamento da lógica de negócios. Usuário do usuário = novo usuário (); // Beanutils conclui o encapsulamento dos dados em um objeto Java Bean, apache uma implementação de jarra de código aberto da fundação. Tente {// Pré -requisito: o nome do campo do Javabean deve ser consistente com a chave do valor enviado no formulário, caso contrário, o encapsulamento não poderá ser concluído. Beanutils.populate (usuário, request.getParameterMap ()); } catch (Exceção e) {e.printStackTrace (); lançar a nova RuntimeTimeException ("Desculpe, os dados de encapsulamento falharam"); } // para uma nova classe Java Bean será projetada para implementar a lógica de negócios UserOperation US = new UserOperation (); tente {int feedback = us.regist (usuário); if (feedback == userOperation.Emailexist) {// indica que o endereço de email já existe request.setAttribute ("mensagem", "o endereço de email já existe"); request.getRequestDispatcher ("regist.jsp"). Forward (solicitação, resposta); } else if (feedback == userOperation.UserNameExist) {// indica que o nome do usuário já existe request.setAttribute ("mensagem", "o nome do usuário já existe"); request.getRequestDispatcher ("regist.jsp"). Forward (solicitação, resposta); } else {// indica que o registro é bem -sucedido e pule para a página de login. Usar o Redirect Response.sendRedirect ("login.jsp"); }} catch (Exceção e) {e.printStackTrace (); lançar a nova RuntimeTimeException ("Adicionar falhou"); }} public void DoPost (solicitação httpServletRequest, httpServletResponse resposta) lança servletexception, ioexception {doget (solicitação, resposta); }}Classe CheckImageServlet
pacote com.vs2022.Controller; importar java.io.ioException; importar javax.servlet.servletexception; importar javax.servlet.http.httpServlet; importar 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", "sem cache"); Response.setheader ("Cache-Control", "No-Cache"); Response.SetDateHeader ("Expira", 0); Response.setContentType ("Image/jpeg"); int width = 40; int altura = 30; // gerar objeto anônimo do código de verificação e gerar código de verificação new CheckCode (). GetCode (largura, altura, solicitação, resposta); } public void DoPost (solicitação httpServletRequest, httpServletResponse resposta) lança servletexception, ioexception {doget (solicitação, resposta); }} Defina classes de ferramentas
DBUTIL CLASS
pacote com.vs2022.utils; importar java.sql.*; importar com.vs2022.model.user; classe pública dbutil {boolean binited = false; // carregar driver public void initjdbc () lança classeNotFoundException {// Carregar MySQL JDBC Driver Class.ForName ("com.mysql.jdbc.driver"); binitado = true; System.out.println ("Sucesso carregando driver MySQL!"); } conexão pública getConnection () lança classNotFoundException, sqLexception {if (! binited) {initjdbc (); } // O URL da conexão é JDBC: MySQL // Endereço do servidor/Nome do banco de dados // Os dois parâmetros a seguir são nome de usuário e conexão de senha Connect = DriverManager.getConnection ("JDBC: MySQL: // Localhost: 3306/Database", "Username", "Senha"); retornar Conn; } public boolean LogInsuccess (nome de usuário da string, senha da string) {boolean returnValue = false; String sql = "selecione * do usuário onde o nome de usuário =? E senha =?"; Conexão conn = null; Preparado estatement ps = null; int i = 0; tente {conn = getConnection (); ps = Conn.Preparestatement (SQL); ps.SetString (1, nome de usuário); ps.SetString (2, senha); ResultSet rs = ps.executeQuery (); if (rs.Next ()) {returnValue = true; }} catch (classNotFoundException e) {e.printStackTrace (); } catch (sqLexception e) {e.printStackTrace (); } retornar retornarValue; } public boolean updateUser (usuário do usuário) {bandeira booleana = false; int i = 0; Conexão conn = null; Preparado estatement ps = null; String sql = "Insira no usuário (nome de usuário, senha, apelido, email) valores (?,?,?)"; tente {conn = getConnection (); ps = Conn.Preparestatement (SQL); ps.SetString (1, user.getUserName ()); // Defina o valor para o espaço reservado. A ordem do espaço reservado começa a partir de 1. O primeiro parâmetro é a posição do espaço reservado, e o segundo parâmetro é o valor do espaço reservado. 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 (); } retornar sinalizador; } public boolean serchusername (string userName) {boolean returnValue = false; String sql = "selecione * do usuário onde o nome de usuário =?"; Conexão conn = null; Preparado estatement ps = null; tente {conn = getConnection (); ps = Conn.Preparestatement (SQL); ps.SetString (1, nome de usuário); ResultSet rs = ps.executeQuery (); if (rs.Next ()) {returnValue = true; }} catch (classNotFoundException e) {e.printStackTrace (); } catch (sqLexception e) {e.printStackTrace (); } retornar retornarValue; } public boolean Serchemail (string email) {boolean returnValue = false; String sql = "Selecione * do usuário onde email =?"; Conexão conn = null; Preparado estatement ps = null; int i = 0; tente {conn = getConnection (); ps = Conn.Preparestatement (SQL); ps.SetString (1, email); ResultSet rs = ps.executeQuery (); if (rs.Next ()) {returnValue = true; }} catch (classNotFoundException e) {e.printStackTrace (); } catch (sqLexception e) {e.printStackTrace (); } retornar retornarValue; }}