The MVC structure diagram implemented using Java Web is as follows, where the controller part is implemented using Servlet, the model part is implemented using JavaBean, and most views are implemented using Jsp pages.
Ideological foundation
The working principle of the two-layer structure of JSP+JavaBean should be relatively familiar and easy to understand.
However, one thing must be clear is that the user sends a web page request through the browser. After this request arrives at the server, the corresponding web page is found on the server side. If it is the first request (the second time is not explained and executed), for the JSP, it is necessary to generate a servlet, and then execute the servlet through the servlet engine, embed the result of calling JavaBean into the page and return it to the user's browser.
The essence of the three-layer structure of JSP+JavaBean+Servlet is that there is an additional Controller: Servlet to distribute client browser requests. It will be of great help to understand the role of a Servlet that acts as a controller as preprocessing the client's request. The corresponding relationship between user requests and specific Servlets can be found through the web.xml configuration file. Each Servlet has a specific Servlet object corresponding to it, so the one that handles user requests is a Servlet object inherited from HttpServlet.
!-- JSPC servlet mappings start -- servlet servlet-namems1/servlet-name servlet-classnews.FirstAction/servlet-class /servlet servlet servlet-namems2/servlet-name servlet-classnews.DetailAction/servlet-class /servlet !-- JSPC servlet mappings end -- servlet-mapping servlet-namems1/servlet-name url-pattern/newsmain/url-pattern/servlet-mapping servlet-mapping servlet-namems2/servlet-name url-pattern/newsDetail/url-pattern/servlet-mapping
As shown above, a section of configuration servlet excerpted from web.xml. The first part is mainly used to configure the servlet to be associated with the specific servlet object. The second part is mainly used to configure which servlet is processed by the request. The association of the servlet name is associated with the specific servlet processing object. For example, the request sent by the client browser from /newsmain is processed by the ms1 servlet. The corresponding serlet object news.FirstAction, that is, /newsmain-ms1-news.FirstAction, which is the meaning of the configuration file. Now that I understand that the user/newsmain request will be processed by objects of the news.FirstAction class, so to understand the program, you must understand what the function of FirstAction is. For example, the following is an implementation of FirstAction.
public final class FirstAction extends HttpServlet { protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { DB db = new DB(); HttpSession session = req.getSession(); try { session.setAttribute(Constants.NEWS_LIST_KEY, News .SearchNewsTitle(db)); } catch (Exception e) { e.printStackTrace(); } db.close(); String target = "/P43_News/newsMain.jsp"; resp.sendRedirect(target); } } Through this implementation, we can see that when the server receives a client request to perform News.SearchNewsTitle(db), then puts the return value into the session through session.setAttribute, and then indirectly transfers it to newsMain.jsp through resp.sendRedirect(target). In this way, the corresponding value stored in the session can be obtained through the session.getAttribute function in newsMain.jsp.
Looking back, it is easy to see that the working principle of JSP+JavaBean is different from that of JSP+JavaBean+Servlet. The two-layer structure must place preprocessing in JSP, for example, News.SearchNewsTitle(db), and the three-layer structure first performs preprocessing in the servlet, and then it is equivalent to returning this processing result to JSP through Session, so that JSP pays more attention to the display of the interface.
Login registration module requirements
1 Register
1.1 User registration form (user name, password, email, nickname, verification code)
1.2 Submit registration: Verification to (user name, password, email, nickname, verification code).
1.2.1 The user name, password, email, and nickname are completed in the client browser and implemented through JS.
1.2.2 The verification code must be completed on the server-side program.
2. If the verification of the registration form is passed, then the business logic will be judged.
2.1 If the user already exists, tell the user the error message.
2.2 If the email address already exists, tell the user the error message.
2.3 If none exists, proceed to step 3.
3. Save user information to the database
4. Register successfully, jump to the login page
5. Log in
5.1 Send user's login information to the background for verification
5.2 If the verification is successful, jump to the home page
5.3 If the jump fails, jump to the login page and prompt for an error message.
Project directory structure
The source code of the project is divided into four package files, which are used to access models, views, controllers and tool classes. The specific files are as follows:
For the view, we define three JSP pages as follows:
Define the view
login.jsp page
<%@ 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.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Login form</title> </head> <body> <font color="red">${message }</font> <a href="regist.jsp">Register a new account</a> <form action="${pageContext.request.contextPath }/login" method="post"> Username:<input type="text" name="username"><br/> Password:<input type="password" name="password"><br/> <input type="submit" value="Login"></form> </body> </html>index.jsp page
<%@ 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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <font color="red">${message }</font> <% if(request.getSession().getAttribute("username")==null) { response.sendRedirect("login.jsp"); } else{ %> <font color="red">"Welcome: " <%=request.getSession().getAttribute("username").toString() %></font> <% } %></body> </html>regist.jsp page
<%@ 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.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title> User Registered Form</title> <script type="text/javascript"> function changeImage(){ document.getElementById("image").src="${pageContext.request.contextPath }/checkimage?" + new Date().getTime() } function validateForm(){ // Verify username, password, email, nickname var username= document.getElementById("username").value; if(username==""){ alert("username cannot be empty"); return false; } var password= document.getElementById("password").value; if(password==""){ alert("Password cannot be empty"); return false; } var repassword= document.getElementById("repassword").value; if(password!=repassword){ alert("Password must be consistent"); return false; } var nickname= document.getElementById("nickname").value; if(nickname==""){ alert("Nickname cannot be empty"); return false; } // ^//s*//w+(?://.{0,1}[//w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*//.[a-zA-Z]+//s*$ var email= document.getElementById("email").value; if(email.match("^//s*//w+(?://.{0,1}[//w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*//.[a-zA-Z]+//s*$")==null){ alert("Email address is incorrect"); return false; } }</script> </head> <body> <h3>Table of user registration</h3> <font color="red">${message }</font> <form action="${pageContext.request.contextPath }/regist" onsubmit="return validateForm();" method="post"> <table> <tr> <td>Username</td> <td> <input type="text" name="username" id="username1" v> </td> </tr> <tr> <td>Password</td> <td> <input type="password" name="password" id="password"> </td> </tr> <tr> <td>Please confirm the 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>Verification code</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="submit" value="registration"> </td> </tr> </table> </form></body> </html> Define the model
User model:
package com.vs2022.model;public class User { private String username; private String password; private String nickname; private String email; // alt+shft+ s // A dialog box for overwriting method pops up. 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 = password; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; }}UserOperation Model
package com.vs2022.model;import com.vs2022.utils.DBUtil;public class UserOperation { public final static int USERNAMEEXIST=1; public final static int EMAILEXIST=2; public final static int SUCCESS=3; public final static int FAIL=4; public int registration(User user){ DBUtil db = new DBUtil(); if(db.serchUserName(user.getUsername())){ // Indicate that the user name already exists return USERNAMEEXIST; } if(db.serchEmail(user.getEmail())){ // It means that the email address already exists. Return EMAILEXIST; } // If you walk here, it means that the email address username is not stored, so let it register. Add to the database db.updateUser(user); return SUCCESS; } public int login(User user) { DBUtil db = new DBUtil(); if(db.loginSuccess(user.getUsername(), user.getPassword())){ // It means that the username and password are correct have been found. Return SUCCESS; } return FAIL; }} CheckCode model
package 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 height, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ // Create image in memory BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g=image.getGraphics(); //Create Graphics object, its function is equivalent to the brush g.setColor(Color.getColor("F8F8F8")); g.fillRect(0, 0, width, height); //Draw the background Font mfont=new Font("KaiTi",Font.BOLD,16); //Define the font style g.setFont(mfont); //Set the font g.setColor(Color.RED); //Generate random number String rans=getRandomString(); //Write random number to session HttpSession session = request.getSession(); session.setAttribute("check", rans); //Write random number to image g.drawString(rans, 5, 20); //Image effective g.dispose(); //Output image ImageIO.write(image, "JPEG", response.getOutputStream());}} Define the controller
LoginServlet class
package 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;import com.vs2022.model.UserOperation;public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Logical Logical String username = request.getParameter("username"); String password = request.getParameter("password"); User user = new User(); user.setUsername(username); user.setPassword(password); // Call the business function javabean class to implement the specific business logic of login UserOperation us = new UserOperation(); // Return value? int i = us.login(user); if(i==4){ // It indicates that the login failed, the username or password was incorrect request.setAttribute("message", "username or password was incorrect"); request.getRequestDispatcher("login.jsp").forward(request, response); }else{ // Login successfully, jump to the homepage of the website, use redirection // Save username into the session domain request.getSession().setAttribute("username", username); response.sendRedirect("index.jsp"); //request.getRequestDispatcher("index.jsp").forward(request, response); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}RegistServlet class
package 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;public class RegistServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Solve the garbled code request.setCharacterEncoding("UTF-8"); // Complete verification of verification code String checkcode = request.getParameter("checkcode"); String check_code_session = (String) request.getSession().getAttribute("check"); if(checkcode==null||!checkcode.equals(check_code_session)){ // Indicate that the verification code is input incorrectly request.setAttribute("message", "Incorrect verification code is input incorrectly"); request.getRequestDispatcher("regist.jsp").forward(request, response); return; } // If you get here, it means that all verifications have passed, and the call involves processing business logic. User user = new User(); // beanUtils Complete the encapsulation of the data into a java bean object, apache An open source jar implementation of the foundation. try { // Prerequisite: The field name of the javabean must be consistent with the key of the value submitted in the form, otherwise the encapsulation cannot be completed. BeanUtils.populate(user, request.getParameterMap()); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Sorry, the encapsulation data failed"); } // So a new java bean class will be designed to implement business logic UserOperation us = new UserOperation(); try { int feedBack = us.regist(user); if(feedBack==UserOperation.EMAILEXIST){ // Indicates that the email address already exists request.setAttribute("message", "The email address already exists"); request.getRequestDispatcher("regist.jsp").forward(request, response); }else if(feedBack==UserOperation.USERNAMEEXIST){ // Indicates that the user name already exists request.setAttribute("message", "The user name already exists"); request.getRequestDispatcher("regist.jsp").forward(request, response); }else{ // Indicates that the registration is successful and jump to the login page. To use redirect response.sendRedirect("login.jsp" ); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Add failed"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}CheckImageServlet class
package 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 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"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); int width=40; int height=30; //Generate anonymous object of the verification code and generate verification code new CheckCode().getCode(width,height,request,response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }} Define tool classes
DBUtil class
package com.vs2022.utils;import java.sql.*; import com.vs2022.model.User;public class DBUtil { boolean bInited = false; // Load driver public void initJDBC() throws ClassNotFoundException { // Load MYSQL JDBC driver Class.forName("com.mysql.jdbc.Driver"); bInited = true; System.out.println("Success loading Mysql Driver!"); } public Connection getConnection() throws ClassNotFoundException, SQLException { if (!bInited) { initJDBC(); } // The connection URL is jdbc:mysql//Server address/Database name//The following two parameters are login username and password Connection conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/Database", "Username", "Password"); return conn; } public boolean loginSuccess(String userName, String password) { boolean returnValue = false; String sql = "SELECT * FROM user where username=? and password=?"; Connection conn = null; PreparedStatement ps=null; int i=0; try { conn = getConnection(); ps=conn.prepareStatement(sql); ps.setString(1, userName); ps.setString(2, password); ResultSet rs=ps.executeQuery(); if(rs.next()){ returnValue=true; } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return returnValue; } public boolean updateUser(User user) { boolean flag=false; int i=0; Connection conn=null; PreparedStatement ps=null; String sql= "insert into user (username,password,nickname,email) values(?,?,?,?)"; try { conn = getConnection(); ps=conn.prepareStatement(sql); ps.setString(1, user.getUsername()); //Set the value for the placeholder. The placeholder order starts from 1. The first parameter is the position of the placeholder, and the second parameter is the value of the placeholder. 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(); } return flag; } public boolean serchUserName(String userName){ boolean returnValue = false; String sql = "SELECT * FROM user where username=?"; Connection conn = null; PreparedStatement ps=null; try { conn = getConnection(); ps=conn.prepareStatement(sql); ps.setString(1, userName); ResultSet rs=ps.executeQuery(); if(rs.next()){ returnValue=true; } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return returnValue; } public boolean serchEmail(String email){ boolean returnValue = false; String sql = "SELECT * FROM user where email=?"; Connection conn = null; PreparedStatement ps=null; int i=0; try { 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(); } return returnValue; }}