本次要分享的内容是使用Servlet技术实现最简单的从页面到后台的一个简化版的教务系统功能模块。在讲述系统之前,首先需要了解一下JavaWeb中的MVC分层重要思想,请看下图:
MVC分层思想把软件系统分为View(视图层),Controller(控制层),Model(模型层),通过这三层结构。让页面请求必须通过控制器处理后调用相应的业务才能拿取数据然后跳转页面,让软件的安全性得到一定程度的提高,最终要的用途还是实现各个层次的分开管理,让软件达到低耦合,高内聚的效果。明确这种思想可以让我们的编程思路更加的清晰明了。
首先我们创建一个web项目,然后根据MVC思想分别建包,如图所示:
项目建包完毕后,需要添加数据库表,教务系统中肯定需要用户,所以创建一张用户表,建表语句如下:
drop table if exists sys_user;
/*==============================================================*/
/* Table: sys_user */
/*==============================================================*/
create table sys_user
(
user_id int(11) not null auto_increment comment '用户id',
name varchar(225) comment '名称',
sex varchar(225) comment '性别',
age varchar(225) comment '年龄',
username varchar(225) comment '用户名',
password varchar(225) comment '密码',
phone varchar(225) comment '注册手机',
email varchar(225) comment '注册邮箱',
created datetime comment '创建时间',
updated datetime comment '修改时间',
primary key (user_id)
);
alter table sys_user comment '用户';
到此基本的准备工作已经差不多了,现在进入到项目中,通过业务分析,首先需要的就是实现登录功能,因此需要制作一个登录页面,还需要创建对应承载数据的实体类,创建一个jsp页面作为登录页,放置两个输入框用于接收用户名和密码,再放置两个按钮用于提交和重置。效果图如下:
jsp代码如下:
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP - Hello World</title>
</head>
<body>
<div align="center">
<font color="red"> ${message}</font>
<form action="${pageContext.servletContext.contextPath}/loginController?method=login" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" value="lh"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password" value="123"></td>
</tr>
<tr>
<td><input type="submit" value="登录"></td>
<td><input type="reset" value="重置"></td>
</tr>
</table>
</form>
</div>
</body>
</html>
系统用户实体类代码:
package com.cdtu.system.domain;
/**
* @author:lxj
* @date 2023/7/26 17:13
* 功能:角色类
*/
public class SysRole {
private int role_id;//角色ID
private String role_name;//角色名称
private String state;//状态
private String decs;//描述
public SysRole() {
}
public SysRole(int role_id, String role_name, String state, String decs) {
this.role_id = role_id;
this.role_name = role_name;
this.state = state;
this.decs = decs;
}
public int getRole_id() {
return role_id;
}
public void setRole_id(int role_id) {
this.role_id = role_id;
}
public String getRole_name() {
return role_name;
}
public void setRole_name(String role_name) {
this.role_name = role_name;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getDecs() {
return decs;
}
public void setDecs(String decs) {
this.decs = decs;
}
@Override
public String toString() {
return "SysRole{" +
"role_id=" + role_id +
", role_name='" + role_name + '\'' +
", state='" + state + '\'' +
", decs='" + decs + '\'' +
'}';
}
}
页面完成之后接下来写控制器,由于要经常使用servlet技术这里使用一个工具类封装好HttpServlet要使用的类继承即可使用。使用@WebServlet注解映射跳转访问路径,然后控制器通过request拿到前台页面输入的用户名和密码,调用服务层的方法,返回数据层从数据库获取的对象信息,把其中的用户名和密码进行比对,若完全匹配就登录跳转到主页面,否则就显示用户名或密码错误。登录控制层代码:
/**
* @author:lxj
* @date 2023/7/24 16:08
* 功能:登录控制器类
*/
@WebServlet("/loginController")
public class LoginController extends Base2Controller {
IService service = new ServiceImpl();
SysUser user = new SysUser();
public String login(HttpServletRequest req, HttpServletResponse resp){
//接收数据
String username = req.getParameter("username");
String password = req.getParameter("password");
// 调用业务
SysUser sysUser_db = sysUserService.queryUserByUsername(username);
//业务判断
if(sysUser_db != null){
if(password.equals(sysUser_db.getPassword())){
//友情提示
req.setAttribute("message","登录成功!");
//登录成功,取出登录用户自己的权限
// 使用Session保存用户的信息
HttpSession session = req.getSession();
session.setAttribute("USER",sysUser_db);
//############################## 取出登录用户自己权限
// Object user = session.getAttribute("USER");
//跳转主页面
return "view/frame/main.jsp";
}
else {
//友情提示
req.setAttribute("message","用户名或密码错误,请重新输入!");
//跳转登录页面
return "index.jsp";
}
}else {
//友情提示
req.setAttribute("message","用户名或密码错误,请重新输入!");
//跳转登录页面
return "index.jsp";
}
}
}
登录成功界面:
主页面jsp代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>主页面</title>
</head>
<body>
<div align="center">
<h3>主页面</h3>
<font color="red"> ${message}</font>
<hr>
<h3>1.系统管理</h3>
<a href="${pageContext.servletContext.contextPath}/sysUserController?method=list">用户列表</a><br>
<a href="${pageContext.servletContext.contextPath}/sysRoleController?method=list">角色列表</a><br>
<a href="${pageContext.servletContext.contextPath}/sysPermissionController?method=list">权限列表</a><br>
<h3>2.邮件管理</h3>
<a href="#">写邮件</a><br>
<a href="#">收件箱</a><br>
<a href="#">发件箱</a><br>
<a href="#">草稿箱</a><br>
<a href="#">垃圾箱</a><br>
<h3>3.选课管理</h3>
<a href="#">选课</a><br>
<a href="#">退课</a><br>
</div>
</body>
</html>
系统管理模块下有3个分支功能:分别是用户列表、角色列表、权限列表,今天只讲述用户列表中的增删改查业务逻辑实现。创建一个系统用户控制层类,类名为SysUserController,所有关于系统用户相关的控制都在该类中进行,首先通过点击用户列表跳转后会显示数据库中所有的用户信息,此处调用服务层方法查询数据库所有的用户信息,并将得到的用户集合对象通过req.setAttribute()键值对的形式返回给页面,页面拿到用户集合对象进行遍历和解析,最终显示在页面上。查询全部控制层代码:
/**
* 查询全部用户数据
* @param req
* @param resp
* @return
*/
public String list(HttpServletRequest req, HttpServletResponse resp){
List<SysUser> userList = sysUserService.queryAllUser();
//返回数据
req.setAttribute("userList",userList);
// 跳转页面
return "view/system/sysuser/sysuser.jsp";
}
service层代码:
List<SysUser> queryAllUser();//接口层
public List<SysUser> queryAllUser() {//实现层
return sysUserDao.queryAllUser();
}
dao层代码:
//操作数据库
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
@Override
public List<SysRole> queryAllRole() {
try {
conn = JdbcUtils.getConnection();
String sql = "select * from sys_role";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
ArrayList<SysRole> roles = new ArrayList<>();
while(rs.next()){
SysRole sysRole_db = new SysRole();
sysRole_db.setRole_id(rs.getInt("role_id"));
sysRole_db.setRole_name(rs.getString("role_name"));
sysRole_db.setState(rs.getString("state"));
sysRole_db.setDecs(rs.getString("decs"));
roles.add(sysRole_db);
}
return roles;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
jsp页面代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<div align="center">
<h1>欢迎进入用户列表</h1>
<p><a href="${pageContext.servletContext.contextPath}/view/system/sysuser/addSysUser.jsp">增加</a></p>
<table border="1px" width="90%">
<tr>
<td>ID</td>
<td>姓名</td>
<td>性别</td>
<td>年龄</td>
<td>手机号</td>
<td>邮件</td>
<td colspan="2">操作</td>
</tr>
<c:forEach items="${userList}" var="user">
<tr>
<td>${user.user_id}</td>
<td>${user.name}</td>
<td>${user.sex}</td>
<td>${user.age}</td>
<td>${user.phone}</td>
<td>${user.email}</td>
<td><a href="${pageContext.servletContext.contextPath}/sysUserController?method=updateUI&id=${user.user_id}">修改</a></td>
<td><a href="${pageContext.servletContext.contextPath}/sysUserController?method=delete&id=${user.user_id}">删除</a></td>
<td><a href="${pageContext.servletContext.contextPath}/sysRoleController?method=fpRoleUI&id=${user.user_id}">分配角色</a></td>
</tr>
</c:forEach>
</table>
<p> </p>
<input type="button" value="首页">
<input type="button" value="上一页">
<input type="button" value="1">
<input type="button" value="2">
<input type="button" value="3">
<input type="button" value="4">
<input type="button" value="5">
<input type="button" value="6">
<input type="button" value="7">
<input type="button" value="8">
<input type="button" value="9">
<input type="button" value="10">
<input type="button" value="下一页">
<input type="button" value="尾页">
</div>
</body>
</html>
查询所有用户信息效果图:
实现用户增加功能,先编写增加用户界面,jsp代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
<head>
<title>添加用户</title>
</head>
<body>
<div align="center">
<h1>添加用户</h1>
<form action="${pageContext.servletContext.contextPath}/sysUserController?method=add" method="post">
<table>
<tr>
<td>姓名</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>性别</td>
<td><input type="text" name="sex"></td>
</tr>
<tr>
<td>年龄</td>
<td><input type="text" name="age"></td>
</tr>
<tr>
<td>手机号</td>
<td><input type="text" name="phone"></td>
</tr>
<tr>
<td>邮件</td>
<td><input type="text" name="email"></td>
</tr>
<tr>
<td>用户名</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="text" name="password"></td>
</tr>
<tr>
<td><input type="submit" value="增加"></td>
<td><input type="reset" value="重置"></td>
</tr>
</table>
</form>
</div>
</body>
</html>
效果图如下:
添加用户控制层,通过request获取页面传递过来的姓名,性别,年龄,手机号,邮箱,用户名和密码数据,同理使用service层调用数据层进行添加数据,然后刷新页面数据,在跳转回查询全部用户信息界面。控制层代码:
/**
* 添加用户功能
* @param req
* @param resp
* @return
*/
public String add(HttpServletRequest req, HttpServletResponse resp){
SysUser sysUser = new SysUser();
String name = req.getParameter("name");
String sex = req.getParameter("sex");
String age = req.getParameter("age");
String phone = req.getParameter("phone");
String email = req.getParameter("email");
String username = req.getParameter("username");
String password = req.getParameter("password");
sysUser.setName(name);
sysUser.setSex(sex);
sysUser.setAge(age);
sysUser.setPhone(phone);
sysUser.setEmail(email);
sysUser.setUsername(username);
sysUser.setPassword(password);
sysUser.setCreated(new Date());
sysUser.setUpdated(new Date());
boolean flag = sysUserService.addUser(sysUser);
this.list(req, resp);
return "view/system/sysuser/sysuser.jsp";
}
service层代码:
boolean addUser(SysUser sysUser);//接口层
public boolean addUser(SysUser sysUser) {//实现层
return sysUserDao.addUser(sysUser);
}
dao层代码:
/**
* 添加用户
* @return
*/
@Override
public boolean addUser(SysUser sysUser) {
try {
conn = JdbcUtils.getConnection();
String sql = "insert into sys_user(`name`,sex,age,phone,email,username,password,created,updated) values (?,?,?,?,?,?,?,?,?); ";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1,sysUser.getName());
pstmt.setString(2,sysUser.getSex());
pstmt.setString(3,sysUser.getAge());
pstmt.setString(4,sysUser.getPhone());
pstmt.setString(5,sysUser.getEmail());
pstmt.setString(6,sysUser.getUsername());
pstmt.setString(7,sysUser.getPassword());
pstmt.setObject(8,sysUser.getCreated());
pstmt.setObject(9,sysUser.getUpdated());
int i = pstmt.executeUpdate();
if (i > 0){
//添加成功
return true;
}else{
//添加失败
return false;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return false;
}
接下来是较为简单的删除用户操作,根据页面请求路径中携带的用户id参数进行对数据库匹配删除,然后刷新页面数据,在跳转回查询全部用户信息界面。控制层代码:
/**
* 删除用户
* @param req
* @param resp
* @return
*/
public String delete(HttpServletRequest req, HttpServletResponse resp){
String id = req.getParameter("id");
boolean flag = sysUserService.deleteUser(id);
this.list(req,resp);
return "view/system/sysuser/sysuser.jsp";
}
service层代码:
boolean deleteUser(String id);//接口层
public boolean deleteUser(String id) {//实现层
return sysUserDao.deleteUser(id);
}
dao层代码:
@Override
public boolean deleteUser(String id) {
try {
conn = JdbcUtils.getConnection();
String sql = "delete from sys_user where user_id = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1,id);
int i = pstmt.executeUpdate();
if(i>0){
//删除成功
return true;
} else {
//删除失败
return false;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return false;
}
最后是稍微复杂一点的修改功能,先编写修改用户界面,jsp代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
<head>
<title>修改用户</title>
</head>
<body>
<div align="center">
<h1>修改用户</h1>
<form action="${pageContext.servletContext.contextPath}/sysUserController?method=update" method="post">
<input type="hidden" name="user_id" value="${sysUser.user_id}" >
<input type="hidden" name="created" value="${sysUser.created}" >
<table>
<tr>
<td>姓名</td>
<td><input type="text" name="name" value="${sysUser.name}"></td>
</tr>
<tr>
<td>性别</td>
<td><input type="text" name="sex" value="${sysUser.sex}"></td>
</tr>
<tr>
<td>年龄</td>
<td><input type="text" name="age" value="${sysUser.age}"></td>
</tr>
<tr>
<td>手机号</td>
<td><input type="text" name="phone" value="${sysUser.phone}"></td>
</tr>
<tr>
<td>邮件</td>
<td><input type="text" name="email" value="${sysUser.email}"></td>
</tr>
<tr>
<td>用户名</td>
<td><input type="text" name="username" value="${sysUser.username}"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="text" name="password" value="${sysUser.password}"></td>
</tr>
<tr>
<td><input type="submit" value="增加"></td>
<td><input type="reset" value="重置"></td>
</tr>
</table>
</form>
</div>
</body>
</html>
用户修改界面效果图:
修改用户控制层,先调用updateUI()方法实现页面跳转,根据页面请求路径中携带的用户id参数获取对应的用户对象并返回给页面,在调用update()方法通过request获取页面修改过后传递过来的姓名,性别,年龄,手机号,邮箱,用户名和密码数据,使用service层调用数据层进行实现真正的修改数据,然后刷新页面数据,在跳转回查询全部用户信息界面。控制层代码:
/**
* 跳转用户修改页面
* @param req
* @param resp
* @return
*/
public String updateUI(HttpServletRequest req, HttpServletResponse resp){
//接收数据
String id = req.getParameter("id");
Integer user_id = Integer.valueOf(id);
//调用业务,根据id查询用户对象
SysUser sysUser = sysUserService.queryUserById(user_id);
//返回数据
req.setAttribute("sysUser",sysUser);
//跳转页面
return "view/system/sysuser/updateSysUser.jsp";
}
/**
* 用户修改
* @param req
* @param resp
* @return
* @throws ParseException
*/
public String update(HttpServletRequest req, HttpServletResponse resp) throws ParseException {
//接收数据
SysUser sysUser = new SysUser();
String id = req.getParameter("user_id");
Integer user_id = Integer.valueOf(id);
String name = req.getParameter("name");
String sex = req.getParameter("sex");
String age = req.getParameter("age");
String phone = req.getParameter("phone");
String email = req.getParameter("email");
String username = req.getParameter("username");
String password = req.getParameter("password");
String createdSTR = req.getParameter("created");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date created = simpleDateFormat.parse(createdSTR);
//封装数据
sysUser.setUser_id(user_id);
sysUser.setName(name);
sysUser.setSex(sex);
sysUser.setAge(age);
sysUser.setPhone(phone);
sysUser.setEmail(email);
sysUser.setUsername(username);
sysUser.setPassword(password);
sysUser.setCreated(created);
sysUser.setUpdated(new Date());
System.out.println(sysUser);
// 调用业务
int n = sysUserService.updateUser(sysUser);
this.list(req, resp);
//跳转页面
return "view/system/sysuser/sysuser.jsp";
}
service层代码:
int updateUser(SysUser sysUser);//接口层
@Override
public int updateUser(SysUser sysUser) {//实现层
return sysUserDao.updateUser(sysUser);
}
dao层代码:
@Override
public int updateUser(SysUser sysUser) {
try {
conn = JdbcUtils.getConnection();
String sql = "update sys_user set name = ? , sex = ? , age = ? ,username = ?, password = ? ,phone = ? ,email = ?,created = ?,updated = ? where user_id = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1,sysUser.getName());
pstmt.setString(2,sysUser.getSex());
pstmt.setString(3,sysUser.getAge());
pstmt.setString(4,sysUser.getUsername());
pstmt.setString(5,sysUser.getPassword());
pstmt.setString(6,sysUser.getPhone());
pstmt.setString(7,sysUser.getEmail());
pstmt.setObject(8,sysUser.getCreated());
pstmt.setObject(9,sysUser.getUpdated());
pstmt.setInt(10,sysUser.getUser_id());
int i = pstmt.executeUpdate();
return i;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return 0;
}
到此基于Servlet技术的教务系统中系统管理模块下的用户列表的增删改查就介绍完毕了。