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:
- Service layer: mainly responsible for processing business, such as modifying commodity inventory according to user’s order information.
- 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:
-
- 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.
-
- The form on the login page is a POST request, and the request path should also be added
${path}
, such as:
- The form on the login page is a POST request, and the request path should also be added
<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.