preface

These two days have nothing to do, with servlet and JSP to do a simple student management system.

The reason for doing this system is that I talked a lot about the basics of javaweb earlier:

I want to string together these knowledge, so that the partners who are learning this piece of knowledge really understand the development process of Web projects.

1. Project demonstration

Note: because I mainly want to explain the process of system development, so only realize the function of student management. We can improve the follow-up function, it is practice.

1.1 Administrator Login

Login failed

Login successful

Not logged in to access other resources

1.2 the query

Query data:

No data is found:

Clear query criteria:

1.3 New Students

1.4 Modifying students

1.5 Deleting students

1.6 quit

2. System environment

2.1 Development Tools

  • Back-end development tool: IDEA
  • Front-end development tool: VSCODE
  • Database connection tool: Navicat

2.2 technology stack

Front end:

  • html+css+JavaScript
  • Framework: Juery + the BootStrap

The backend:

  • The JDK: jdk8
  • Technology: the Jsp + Servlet
  • Database: Mysql
  • Tomcat: Tomcat9

3. Database design

The core resource of a website is data, which is stored in a database. So the premise of website development is to design the database first.

And the database design is based on the needs of users.

What are the user needs? The requirement is what are we going to develop this site for? What functions does this site have?

3.1 Administrator Information table

The website we developed is a student management system, since it is a management system, there must be administrators, so there needs to be an administrator table to store administrator information.

The administrator must be logged in to access the system, so the administrator table must contain the account and password, and of course the primary key ID.

3.2 Student information sheet

The website we developed is used to manage student information, so it is necessary to have a student information table to store student information.

The student form should contain important information about the student: name, gender, age, etc.

3.3 Class information table

In addition to knowing the students’ information, we also want to know what about the class the students are in? You need a class list.

The class table must have the name of the class.

3.4 Maintaining relationships between tables

We know that a class contains multiple students, so the class information and student information are one-to-many. According to the database design paradigm, the id of the one party needs to be stored in the many party.

So the student table needs to have the id of the class table.

3.5 Expand the table as required

Since I was just doing a small demo, I designed only three tables: administrator table, class table, and student table.

You can increase the table according to the expanded function, such as the increase of teacher table, grade table and so on.

3.6 Creating databases and tables

Database: student_system

Administrator table: s_admin

CREATE TABLE `s_admin` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT 'id',
  `username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'account',
  `password` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'password'.PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
Copy the code

Student table: s_student

CREATE TABLE `s_student` (
  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  `class_id` int DEFAULT NULL COMMENT 'class id',
  `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'name',
  `sex` tinyint(1) DEFAULT NULL COMMENT '0- Female 1- Male ',
  `age` int DEFAULT NULL COMMENT 'age'.PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
Copy the code

Class table: s_class

CREATE TABLE `s_class` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT 'id',
  `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Class Name'.PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
Copy the code

Complete table structure:

4. Project construction

4.1 Creating a Project

File -> new -> Project

4.2 Loading required JAR Packages

Right-click the lib directory and Add as Library.

4.3 Improve the project catalog

  • Controller: stores servlets
  • Dao: Persistence layer that works with databases
  • File: stores the configuration file for connecting to mysql
  • Filter: Stores the filter
  • Model: Stores entity classes
  • Service: business processing layer
  • Util: Stores utility classes
  • Static: Stores static resources, such as CSS, JS, and images
  • View: Stores the JSP file

5. Configure tomcat

Deployment project

Configure the default access path for the project

6. Configure the default access page

We know that a JavaWeb project will access files like index.jsp and index.html by default when it starts.

However, the administrator needs to log in to enter the system, so you need to configure the default startup page of the project in web.xml to be the login page:


      
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <! -- Enter the login page by default -->
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
</web-app>
Copy the code

7. Create an entity class

Entity classes and tables in the database are mapped one by one. When creating the class class, note that the English class is the Java keyword, so I changed it to Classes.

/** * class entity */
public class Classes {
    // id
    private int id;
    // Class name
    private String name;

    public int getId(a) {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name; }}Copy the code

In addition to the Admin, Student, and Classes Classes, I also created the Page class to encapsulate the paging information.

8. JDBC utility classes

The core resource of the site is data, so we have to deal with databases.

And every time add, edit, delete data need to obtain the connection of the database, and then to operate, it is too troublesome.

What if I don’t want to write a bunch of repetitive code when using Java to connect to a database?

We can encapsulate the code that manipulates the database into a utility class that contains static methods that only need to be used by class names. Method call.

package com.xxx.sms.util;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
/** * public id: know whether technology */
public class JDBCUtils {
    // Database account
    private static String user;
    // Database password
    private static String password;
    // Connect to the database URL
    private static String url;
    // Database driver
    private static String driver;

    static {
        // The static code block only needs to be loaded once to read the resource file
        try {
            // 1. Load the configuration file
            Properties pro = new Properties();
            pro.load(JDBCUtils.class.getResourceAsStream("/com/xxx/sms/file/jdbc.properties"));
            System.out.println(pro);
            // 2. Obtain the database connection information from the configuration file
            url = pro.getProperty("url");
            user = pro.getProperty("user");
            password = pro.getProperty("password");
            driver = pro.getProperty("driver");
            // 3. Create a database connection driver
            Class.forName(driver);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch(ClassNotFoundException e) { e.printStackTrace(); }}// 4. Obtain the connection object
    public static Connection getConnection(a) throws SQLException {
        return DriverManager.getConnection(url, user, password);
    }

    // 5. Release resources
    public static void close(PreparedStatement ps, Connection conn) {
        close(null, ps, conn);
    }

    // 6. Free resources (overload)
    public static void close(ResultSet rs, PreparedStatement ps, Connection conn) {
        if (null! = rs) {try {
                rs.close();
            } catch(SQLException e) { e.printStackTrace(); }}if (null! = ps) {try {
                ps.close();
            } catch(SQLException e) { e.printStackTrace(); }}if (null! = conn) {try {
                conn.close();
            } catch(SQLException e) { e.printStackTrace(); }}}}Copy the code

The jdbc.properties file contains some configuration information for the database:

url=jdbc:mysql://localhost:3306/student_system
user=root
password=12345678
driver:com.mysql.jdbc.Driver
Copy the code

9. Filter Intercepts requests

We know that the resources in the website are not easily accessible. For example, you cannot add goods to the shopping cart without logging on to Taobao.

The filter is used to intercept user requests.

In this system, we need to determine whether the administrator is logged in, and if so, we will allow, and if not, we will redirect to the login page.

Of course, if we encounter login, exit, static resources, we also need to release.

AccessFilter:

@WebFilter(filterName = "accessFilter", urlPatterns = "/*")
public class AccessFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpSession session = request.getSession();
        // 1. Get the URI: for example, / SMS /student/list
        String url = request.getRequestURI();
        // 2. Because the default configuration of the welcome page in web.xml is the login page, and the project enters the login page at the end of the URL is/SMS /
        // Exclude logins, logouts, and static resources
        if (url.endsWith("/sms/") || url.contains("/login") || url.contains("/logout") || url.contains("/static/")) {
            / / 3. The release
            filterChain.doFilter(request, response);
        } else {
            // 4. Check whether admin is logged in before requesting other resources. If not, redirect to the login page
            Admin admin = (Admin) session.getAttribute("admin");
            // 5. The administrator has logged in
            if (null! = admin) {/ / 6. Release
                filterChain.doFilter(request, response);
            } else {
                // 7. Redirect login.jsp, please login before accessing other resources
                response.sendRedirect(request.getContextPath() + "/login.jsp"); }}}}Copy the code

10. MVC design pattern

10.1 What is the MVC Design Pattern?

When we first started coding, we liked to write a bunch of stinky, long code in a method. For example, in a servlet, you get the user’s request parameters, connect to the database to get the data, and then wrap the data back to the browser.

So the idea of layering code was born to make it easier to maintain code and make it look less disgusting.

Each layer of code does what it does best.

According to the division of functions, we divide the code into three layers, namely Model layer, View layer and Controller layer. The organization of this code is called the MVC pattern.

10.2 Functional division of each layer

  • View: The page we see on a website, which contains HTML, JS, etc., and is mainly responsible for displaying data.
  • Controller: Obtains user request parameters and processes user requests. In this case servlets.
  • Model layer: The Model layer contains two layers:
  1. Service layer: mainly responsible for processing business, such as modifying commodity inventory according to user’s order information.
  2. Dao layer: mainly responsible for dealing with the database, operating data, encapsulating data.

10.3 Call order of code

View -> Controller -> Service -> Dao
Copy the code

The user initiates a request at the View layer (browser), and the Controller layer (servlet) receives the request and calls the Service layer.

The Service layer handles the business logic that calls the Dao layer to retrieve the data after the operation and returns the results to the Controller layer (servlet). The Controller layer (servlet) then sends the response results to the browser (View layer).

11. The login

11.1 the login. The JSP

Because we configured the default access page for the project in web.xml to be login.jsp, we needed to refine the code for the login page.

There are two things to note when writing a login page:

    1. When requesting static resources from the server, we need to add the root path of the project, which is the Application context we configured when configuring Tomcat:

To obtain the project root path in the JSP file, use the following method:

${pageContext.request.contextPath}
Copy the code

Such as:

<link rel="stylesheet" href="${pageContext.request.contextPath}/static/css/login.css">
<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery.js"></script>
Copy the code

However, getting the project root path is a bit cumbersome. We can get it in Java code in the JSP header, and then put it in the global scope. Such as:

<%
String path = request.getContextPath(a); String basePath = request.getScheme() + ": / /"+request.getServerName()+":"+request.getServerPort()+path;
application.setAttribute("path", basePath); % >Copy the code

The value of path is:

http://localhost:8080/sms
Copy the code

We can then refer to the server’s static resources as follows:

<link rel="stylesheet" href="${path}/static/css/login.css">
<script type="text/javascript" src="${path}/static/js/jquery.js"></script>
Copy the code

Using ${path} is certainly much simpler.

    1. The form on the login page is a POST request, and the request path should also be added${path}, such as:
<form action="${path}/login" method="POST">
  <h4 style="color:black; text-align: center; margin-top:35px">Student Management System</h4>
  <div class="form">
      <img src="${path}/static/image/person.png" alt="Account">
      <input type="text" name="username" placeholder="Please enter your account number">
  </div>
  <div class="form">
      <img src="${path}/static/image/password.png" alt="Password">
      <input type="password" name="password" maxlength="6" placeholder="Please enter your password"></div>
  <input type="submit" value="Login">
</form>
Copy the code

11.2 loginServlet

When the administrator opens the login page, enters the account password and clicks the login button, a Servlet is required to process the request.

So we need to write a LoginServlet to handle the administrator’s login request.

That administrator input account password casually can log in to the system background? Definitely not.

Therefore, LoginServlet needs to obtain the account password entered by the administrator, and then invokes the login method of Service. The Service layer invokes the login method of Dao layer, and the Dao layer queries according to the account password passed and from the database. If found, the real information will be returned.

If the information exists in the database, the information will be saved in the Session, and then redirected to the page of the student list, that is, successfully logged into the background of student management.

If this information does not exist in the database, you will be redirected to the login page, prompting you to log in again because your account or password is incorrect.

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. Obtain the username parameter passed by the browser
        String username = request.getParameter("username");
        // 2. Obtain the password parameter passed by the browser
        String password = request.getParameter("password");
        AdminService adminService = new AdminServiceImpl();
        // 3. Invoke the login method at the service layer to obtain the administrator information based on the account and password
        Admin admin = adminService.login(username, password);
        // 4. If the administrator exists
        if (null! = admin) { HttpSession session = request.getSession();// 5. Save the administrator information to the session
            session.setAttribute("admin", admin);
            // 6. Redirect to a user-managed page. Note: Here request.getContextPath() is the root path to get the project
            response.sendRedirect(request.getContextPath()+"/student/list");
        } else {
            // 7. If it does not exist, place the error message in the request field and forward the request to the login page
            request.setAttribute("error"."Wrong account or password!");
            request.getRequestDispatcher("/login.jsp").forward(request,response); }}}Copy the code

12. Manage background pages

The management background page is actually divided into a div according to the functional area. So I’m going to start off by dividing areas on a piece of paper.

Then use vscode to draw the admin background page.

I introduced BootStrap framework to manage the background page. BootStrap is actually JS and CSS styles developed by others, which we can directly introduce and use.

<link rel="stylesheet" href="${path}/static/bootstrap/css/bootstrap.min.css">
<script src="${path}/static/js/jquery.js"></script>
<script src="${path}/static/bootstrap/js/bootstrap.min.js"></script>
Copy the code

The BootStrap website:

https://v3.bootcss.com/
Copy the code

Since JSTL tags are used to display list information, we need to introduce JSTL tag library:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"% >Copy the code

A list of 13.

13.1 ListServlet

After successful login, the administrator is redirected to the page for obtaining the student list. So you need a servlet to get the student’s list information and encapsulate it into a Page class.

/** * public id: know whether technology */
@WebServlet("/student/list")
public class ListServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. Get the current page
        String current = req.getParameter("currentPage");
        // 2. Default is the first page
        int currentPage = (null! = current && current.length() >0)? Integer.parseInt(current) :1;
        // 3. Encapsulate query parameters: name and class ID
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("name",req.getParameter("name"));
        paramMap.put("classId",req.getParameter("classId"));
        StudentService studentService = new StudentServiceImpl();
        // 4. Call the list method of the service layer
        Page<Student> page = studentService.list(currentPage,paramMap);
        ClassesService classesService = new ClassesServiceImpl();
        // 5. Get all class information
        List<Classes> classList = classesService.getClassList();
        // 6. Store all data in the request domain
        req.setAttribute("page", page);
        req.setAttribute("classList", classList);
        req.setAttribute("paramMap", paramMap);
        // 7. Request forward to student-managed JSP page
        req.getRequestDispatcher("/WEB-INF/view/student/list.jsp").forward(req, resp); }}Copy the code

The ListServlet puts the encapsulated data into the Request field, which then forwards the request to the list.jsp page.

13.2 the list. The JSP

List.jsp retrieves the data from the Request field and loops through the student’s information using EL expressions and JSTL tags.

  <c:forEach items="${page.list}" var="student" varStatus="status">
    <tr>
        <td style="vertical-align:middle">${status.index+1}</td>
        <td>${student.name}</td>
        <td>${student.sex==0?" "Woman:" male "}</td>
        <td>${student.age}</td>
        <td>${student.className}</td>
        <td width="20px">
            <a onclick="return showStudentDetailModal('${path}/student/find? id=${student.id}')">
                <button type="button" class="btn btn-default">The editor</button>
            </a>
        </td>
        <td width="20px">
            <a onclick="return showDelStudentModal('${path}/student/delete? id=${student.id}','${student.name}')">
                <button type="button" class="btn btn-danger">delete</button>
            </a>
        </td>
    </tr>
</c:forEach>
Copy the code

14. Add and edit

Add and edit the page I shared with the Bootstrap modal box, click different buttons to display different titles using jquery:

$("#title").text(" New Student Information "); $("#title").text(" Edit student information ");Copy the code

When clicking edit, the student’s information should be displayed first. Here, I used Ajax to request FindServlet to obtain the student’s information:

// Data $is displayed.ajax({
    url: url,
    dataType: "json",
    success: function (data) {
        $("#studentId").val(data.id);
        $("#studentName").val(data.name);
        $("input[name='sex'][value='" + data.sex + "']").attr("checked", true);
        $("#studentAge").val(data.age);
        $("#studentClassId").val(data.classId); }});Copy the code

FindServlet:

/** * public id: know whether technology */
@WebServlet("/student/find")
public class FindServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        StudentService studentService = new StudentServiceImpl();
        // 1. Obtain the id information passed by the browser
        int id = Integer.parseInt(req.getParameter("id"));
        // 2. Call the find method of studentService to obtain the student information
        Student student = studentService.find(id);
        // 3. Set the contentType of the response object to JSON
        resp.setContentType("application/json; charset=utf-8");
        PrintWriter writer = resp.getWriter();
        // 4. Write data to the output streamwriter.println(JSON.toJSONString(student)); writer.flush(); writer.close(); }}Copy the code

Because editing modifies information in the database by ID, editing pages need to have a hidden ID:

<input type="hidden" name="id" id="studentId">
Copy the code

I used the same Servlet to handle additions and edits. The key is whether the data passed contains an ID. If there is an ID, call the Update method on the service layer, otherwise call add.

/** * public id: know whether technology */
@WebServlet("/student/saveOrUpdate")
public class SaveServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. POST requests to set the encoding format to solve the problem of obtaining Chinese garbled characters
        req.setCharacterEncoding("utf-8");
        // 2. Get the id parameter passed by the browser
        String id = req.getParameter("id");
        // 3. Create a student object
        Student student = new Student();
        // 4. Set the ID: If the ID does not exist, set it to 0. Otherwise it's the passed ID
        student.setId(Integer.parseInt(("".equals(id)) ? "0" : req.getParameter("id")));
        // 5. Set student name
        student.setName(req.getParameter("name"));
        // 6. Set student gender
        student.setSex(Integer.parseInt(req.getParameter("sex")));
        // 7. Set the age of students
        student.setAge(Integer.parseInt(req.getParameter("age")));
        // 8. Set student class ID
        student.setClassId(Integer.parseInt(req.getParameter("classId")));
        StudentService studentService = new StudentServiceImpl();
        boolean flag;
        // 9. If the id is 0, the new student information is created
        if (student.getId() == 0) {
            // 10. Call the new method of service
            flag = studentService.add(student);
        } else {
            // 11. Otherwise, call the edit method of service
            flag = studentService.update(student);
        }
        // 12. If it is added or modified successfully, it is redirected to the student list page
        if (flag) {
            resp.sendRedirect(req.getContextPath() + "/student/list"); }}}Copy the code

15. Delete

Click Delete to access DeleteServlet. DeleteServlet gets the passed ID and then calls the DELETE method of the Service layer. The service layer calls the DELETE method of the Dao layer. The Dao layer deletes student information by manipulating the database.

@Override
public boolean delete(int id) {
    try {
        // 1. Obtain the database connection object
        conn = JDBCUtils.getConnection();
        // 2. SQL statement
        String sql = "delete from s_student where id = ?";
        // 3. Create an object to execute SQL
        ps = conn.prepareStatement(sql);
        / / 4 to? The assignment
        ps.setInt(1, id);
        // 5 Execute SQL
        int count = ps.executeUpdate();
        if (count > 0) {
            return true;
        } else {
            return false; }}catch (Exception e) {
        e.printStackTrace();
    } finally {
        // 6. Release resources
        JDBCUtils.close(ps, conn);
    }
    return false;
}
Copy the code

16. Quit

Click the exit button to request the LogoutServlet. After receiving the request, the LogoutServlet clears the administrator information in the session and then redirects to the login page.

<aHref = "${path} / logout" > out of < /a></li>
Copy the code
/** * public id: know whether technology */
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        1. Obtain session data
        HttpSession session = req.getSession(false);
        if (session == null) {
            return;
        }
        // 2. Clear the administrator information in the session
        session.removeAttribute("admin");
        // 3. Redirect to the login page
        resp.sendRedirect(req.getContextPath() + "/login.jsp"); }}Copy the code

17. To summarize

The core of a Web project is that the user initiates a request, then goes through three layers of processing and sends the data back to the browser.

So knowing the process can lead to the development of a complete project.