案例:用户信息管理系统
1.需求
1.1 说明
用户信息列表展示,并且可以对用户信息的进行增删改查操作
1.2 效果图
根据需求,创建效果图,如下:
2.设计
2.1 技术选型
完成本次案例所用使用的相关技术:
Servlet+JSP+MySql+JDBCTemplate+Druid+BeanUtils+tomcat
2.2 数据库设计
本案例使用MySQL数据库,创建数据库和表(为了方便,此处将用户信息表和登录表创建在一张表里)
create database d_user; -- 创建数据库
usr d_user; -- 使用数据库
CREATE TABLE `t_userinfo` ( -- 创建表
`id` INT(11) NOT NULL AUTO_INCREMENT, -- 用户id
`name` VARCHAR(20) NOT NULL, -- 用户名
`sex` VARCHAR(5) DEFAULT NULL, -- 性别
`age` INT(11) DEFAULT NULL, -- 年龄
`address` VARCHAR(32) DEFAULT NULL, -- 地址
`qq` VARCHAR(20) DEFAULT NULL, -- QQ
`email` VARCHAR(50) DEFAULT NULL, -- 邮箱
`username` VARCHAR(32) DEFAULT NULL, -- 登录名
`password` VARCHAR(32) DEFAULT NULL, -- 密码
PRIMARY KEY (`id`) -- 设置主键id
) ENGINE=INNODB DEFAULT CHARSET=utf8 -- 存储引擎Innodb 字符集utf8
2.3 创建项目
创建一个Javaweb项目,结构如下:
2.4 相关jar包
Apache官网http://commons.apache.org/
commons-beanutils-1.9.4.jar下载链接
commons-collections-3.2.2.jar
commons-logging-1.2.jar
commons-pool2-2.9.0.jar
druid-1.0.9.jar
mchange-commons-java-0.2.20.jar
mysql-connector-java-5.1.47.jar
spring-beans-5.0.0.RELEASE.jar
spring-core-5.0.0.RELEASE.jar
spring-jdbc-5.0.0.RELEASE.jar
spring-tx-5.0.0.RELEASE.jar
taglibs-standard-compat-1.2.5.jar
taglibs-standard-impl-1.2.5.jar
taglibs-standard-jstlel-1.2.5.jar
taglibs-standard-spec-1.2.5.jar
3.实现代码
3.1 显示jsp页面
用户信息列表:list.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- 使用Edge最新的浏览器渲染方式 -->
<meta http-equiv="x-ua-compatible" content="IE=edge">
<!-- viewport视口,网页可以根据设置的宽度自动进行适配,在浏览器内部虚拟一个容器,容器的宽度与设置的宽度相同
width:默认宽度与设置的宽度相同
initial-scale:初始值的缩放比,为1:1
-->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签必须放在最前面,任何其他内容都必须跟随其后 -->
<title>用户信息管理系统</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上版本 -->
<script src="js/jquery-3.6.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<script type="text/javascript"></script>
<style type="text/css">
td,th{
text-align: center;
}
.data_count{
font-size: 25px;
margin-left: 5px;
vertical-align: middle;
}
.control_btn{
float: right;
margin: 5px;
}
.serch_form{
float: left;
margin: 5px;
}
</style>
<script>
function deleteUser(id) {
//用户安全提示
if (confirm("您确定要删除吗?")){
//访问路径
location.href = "${pageContext.request.contextPath}/deleteUserServlet?id="+id;
}
}
window.onload = function () {
//给删除选中按钮添加单击事件
document.getElementById("delSelect").onclick = function () {
//提醒用户是否确认删除操作
if(confirm("您确定要删除吗?")){
var flag = false;
var cbs = document.getElementsByName("uid");
//3.遍历每个cb
for (var i = 0; i < cbs.length; i++){
//4.设置这些cbs[i]的checked状态 = firstCb.checked
if (cbs[i].checked){//有条目被选中
flag = true;
break;
}
}
if (flag){
//表单提交
document.getElementById("form").submit();
}
}
}
//1.获取第一个cb
document.getElementById("firstCb").onclick = function () {
//2.获取下面其他的cb
var cbs = document.getElementsByName("uid");
//3.遍历每个cb
for (var i = 0; i < cbs.length; i++){
//4.设置这些cbs[i]的checked状态 = firstCb.checked
cbs[i].checked = this.checked;
}
}
}
</script>
</head>
<body>
<div class="container">
<h3 style="..." align="center">用户信息列表</h3>
<div class="serch_form">
<form class="form-inline" action="${pageContext.request.contextPath}/findUserByPageServlet" method="post">
<div class="form-group">
<label for="exampleInputEmail3">姓名</label>
<input type="text" name="name" class="form-control" value="${condition.name[0]}" id="exampleInputEmail3">
</div>
<div class="form-group">
<label for="exampleInputPassword3">籍贯</label>
<input type="text" name="address" class="form-control" value="${condition.address[0]}" id="exampleInputPassword3">
</div>
<div class="form-group">
<label for="exampleInputPassword2">邮箱</label>
<input type="text" name="email" class="form-control" value="${condition.eamil[0]}" id="exampleInputPassword2">
</div>
<button type="submit" class="btn btn-default">查询</button>
</form>
</div>
<div class="control_btn">
<a class="btn btn-primary" href="${pageContext.request.contextPath}/add.jsp">添加联系人</a>
<a class="btn btn-primary" href="javascript:void(0)" id="delSelect">删除选中</a>
</div>
<form id="form" action="${pageContext.request.contextPath}/delSelectedServlet" method="post">
<table class="table table-bordered table-hover">
<tr class="success">
<th><input type="checkbox" id="firstCb"></th>
<th>编号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>籍贯</th>
<th>QQ</th>
<th>邮箱</th>
<th>操作</th>
</tr>
<c:forEach items="${pb.list}" var="user" varStatus="s">
<tr>
<td><input type="checkbox" name="uid" value="${user.id}"></td>
<td>${s.count}</td>
<td>${user.name}</td>
<td>${user.sex}</td>
<td>${user.age}</td>
<td>${user.address}</td>
<td>${user.qq}</td>
<td>${user.email}</td>
<td><a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/findUserServlet?id=${user.id}">修改</a>
<a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id})">删除</a>
</td>
</tr>
</c:forEach>
</table>
</form>
<div>
<nav aria-label="Page navigation">
<ul class="pagination">
<c:if test="${pb.currentPage == 1}">
<li class="disabled">
</c:if>
<c:if test="${pb.currentPage != 1}">
<li>
</c:if>
<a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${pb.currentPage-1}&rows=${pb.rows}&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<c:forEach begin="1" end="${pb.totalPage}" var="i">
<c:if test="${i == pb.currentPage}">
<li class="active"><a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${i}&rows=${pb.rows}&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}">${i}</a></li>
</c:if>
<c:if test="${i != pb.currentPage}">
<li><a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${i}&rows=${pb.rows}&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}">${i}</a></li>
</c:if>
</c:forEach>
<c:if test="${pb.currentPage >= pb.totalPage}">
<li class="disabled">
</c:if>
<c:if test="${pb.currentPage < pb.totalPage}">
<li>
</c:if>
<a href="${pageContext.request.contextPath}/findUserByPageServlet?currentPage=${pb.currentPage+1}&rows=${pb.rows}&name=${condition.name[0]}&address=${condition.address[0]}&email=${condition.email[0]}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
<span class="data_count">
共${pb.totalCount}条记录,共${pb.totalPage}页
</span>
</ul>
</nav>
</div>
</div>
</body>
</html>
添加操作jsp页面:add.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="UTF-8">
<!-- 使用Edge最新的浏览器渲染方式 -->
<meta http-equiv="x-ua-compatible" content="IE=edge">
<!-- viewport视口,网页可以根据设置的宽度自动进行适配,在浏览器内部虚拟一个容器,容器的宽度与设置的宽度相同
width:默认宽度与设置的宽度相同
initial-scale:初始值的缩放比,为1:1
-->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签必须放在最前面,任何其他内容都必须跟随其后 -->
<title>添加用户</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上版本 -->
<script src="js/jquery-3.6.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<script type="text/javascript"></script>
<style>
div{
text-align: center;
width: 500px;
margin: auto;
}
.error{
color: red;
}
</style>
<script>
window.onload = function () {
document.getElementById("form").onsubmit = function () {
return checkName() && checkAge() && checkAddress() && checkQQ() && checkEmail();
}
document.getElementById("name").onblur = checkName;
document.getElementById("age").onblur = checkAge;
document.getElementById("address").onblur = checkAddress;
document.getElementById("qq").onblur = checkQQ;
document.getElementById("email").onblur = checkEmail;
function checkName() {
reg = /^[\u4e00-\u9fa5]{2,6}$/
var name = document.getElementById("name").value;
var flag = reg.test(name);
var s_username = document.getElementById("s_username");
if (!flag){
s_username.innerHTML = "姓名格式有误";
}
return flag;
}
function checkAge() {
reg = /^\d{0,3}$/
var age = document.getElementById("age").value;
var flag = reg.test(age);
var s_age = document.getElementById("s_age");
if (!flag){
s_age.innerHTML = "年龄格式有误";
}
return flag;
}
function checkAddress() {
reg = /^\w{2,50}$/
var address = document.getElementById("address").value;
var flag = reg.test(address);
var s_address = document.getElementById("s_address");
if (!flag){
s_address.innerHTML = "地址格式有误";
}
return flag;
}
function checkQQ() {
reg = /^\d[1-9][0-9]{4,}$/
var qq = document.getElementById("qq").value;
var flag = reg.test(qq);
var s_qq = document.getElementById("s_qq");
if (!flag){
s_qq.innerHTML = "QQ格式有误";
}
return flag;
}
function checkEmail() {
reg = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/
var email = document.getElementById("email").value;
var flag = reg.test(email);
var s_email = document.getElementById("s_email");
if (!flag){
s_email.innerHTML = "邮箱格式有误";
}
return flag;
}
}
</script>
</head>
<body>
<!-- 添加数据 -->
<div class="container">
<h3 style="..." align="center">添加用户信息</h3>
<div>
<form class="form-horizontal" id="form" action="${pageContext.request.contextPath}/addUserServlet" method="post">
<div class="form-group ">
<label for="name" class="col-sm-2 control-label">姓名</label>
<div class="col-sm-10 form_tr">
<input type="text" name="name" class="form-control" id="name" placeholder="请输入姓名">
</div>
<div class="error_div">
<span id="s_name" class="error"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">性别</label>
<div class="col-sm-10" style="bottom: 1px; text-align: left">
<input type="radio" name="sex" value="男" checked="checked">男
<input type="radio" name="sex" value="女">女
</div>
</div>
<div class="form-group ">
<label for="age" class="col-sm-2 control-label">年龄</label>
<div class="col-sm-10 form_tr">
<input type="text" name="age" class="form-control" id="age" placeholder="请输入年龄">
</div>
<div class="error_div">
<span id="s_age" class="error"></span>
</div>
</div>
<div class="form-group">
<label for="address" class="col-sm-2 control-label">籍贯</label>
<div class="col-sm-10">
<input type="text" name="address" class="form-control" id="address" placeholder="请输入籍贯">
</div>
<div class="error_div">
<span id="s_address" class="error"></span>
</div>
</div>
<div class="form-group">
<label for="qq" class="col-sm-2 control-label">QQ</label>
<div class="col-sm-10">
<input type="text" name="qq" class="form-control" id="qq" placeholder="请输入QQ">
</div>
<div class="error_div">
<span id="s_qq" class="error"></span>
</div>
</div>
<div class="form-group">
<label for="email" class="col-sm-2 control-label">邮箱</label>
<div class="col-sm-10">
<input type="email" name="email" class="form-control" id="email" placeholder="请输入邮箱">
</div>
<div class="error_div">
<span id="s_email" class="error"></span>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="submit" class="btn btn-primary" value="提交">
<button type="reset" id="btn_reset" class="btn btn-default">重置</button>
<button type="button" id="btn_return" class="btn btn-default">返回</button>
</div>
</div>
</form>
</div>
</div>
</body>
</html>
首页jsp页面:index.jsp
<%@ page import="cn.itcast.domain.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<html>
<head>
<meta charset="utf-8">
<!-- 使用Edge最新的浏览器渲染方式 -->
<meta http-equiv="x-ua-compatible" content="IE=edge">
<!-- viewport视口,网页可以根据设置的宽度自动进行适配,在浏览器内部虚拟一个容器,容器的宽度与设置的宽度相同
width:默认宽度与设置的宽度相同
initial-scale:初始值的缩放比,为1:1
-->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签必须放在最前面,任何其他内容都必须跟随其后 -->
<title>首页</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上版本 -->
<script src="js/jquery-3.6.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<script type="text/javascript"></script>
</head>
<body>
<%
User user = (User) request.getAttribute("user");
%>
<div>
${user.name},欢迎您
</div>
<div align="center">
<a href="${pageContext.request.contextPath}/findUserByPageServlet" style="...">查询所有用户信息</a>
</div>
</body>
</html>
登录jsp页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="UTF-8">
<!-- 使用Edge最新的浏览器渲染方式 -->
<meta http-equiv="x-ua-compatible" content="IE=edge">
<!-- viewport视口,网页可以根据设置的宽度自动进行适配,在浏览器内部虚拟一个容器,容器的宽度与设置的宽度相同
width:默认宽度与设置的宽度相同
initial-scale:初始值的缩放比,为1:1
-->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签必须放在最前面,任何其他内容都必须跟随其后 -->
<title>登录</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上版本 -->
<script src="js/jquery-3.6.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<script type="text/javascript">
function refreshCode() {
//1.获取验证码图片对象
var vcode = document.getElementById("vcode");
//2.设置其src属性,加时间戳
vcode.src = "${pageContext.request.contextPath}/checkCodeServlet?time=" + new Date().getTime();
}
</script>
<style type="text/css">
.login_div {
width: 500px;
margin: auto;
}
</style>
</head>
<body>
<div class="login_div">
<h3 style="..." align="center">用户登录</h3>
<form class="form-group" action="${pageContext.request.contextPath}/loginServlet" method="post">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" class="form-control" id="username" name="username" placeholder="请输入用户名">
</div>
<div class="form-group">
<label for="passowrd">密码</label>
<input type="password" class="form-control" id="passowrd" name="password" placeholder="请输入密码">
</div>
<div class="form-group">
<label for="verifycode">验证码</label>
<input type="text" class="" id="verifycode" name="verifycode" placeholder="请输入验证码">
<a href="javascript:refreshCode()">
<img src="${pageContext.request.contextPath}/checkCodeServlet" title="看不清点击刷新" id="vcode">
</a>
</div>
<hr>
<div class="form-group" align="center">
<button type="submit" class="btn btn-primary">登录</button>
</div>
</form>
<!-- 出错显示信息框 -->
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert">
<span>x</span>
</button>
<strong>
<%
Object login_msg = request.getAttribute("login_msg");
%>
${login_msg}
</strong>
</div>
</div>
</body>
</html>
修改用户信息jsp页面:update.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="UTF-8">
<!-- 使用Edge最新的浏览器渲染方式 -->
<meta http-equiv="x-ua-compatible" content="IE=edge">
<!-- viewport视口,网页可以根据设置的宽度自动进行适配,在浏览器内部虚拟一个容器,容器的宽度与设置的宽度相同
width:默认宽度与设置的宽度相同
initial-scale:初始值的缩放比,为1:1
-->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签必须放在最前面,任何其他内容都必须跟随其后 -->
<title>登录</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上版本 -->
<script src="js/jquery-3.6.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<script type="text/javascript">
function refreshCode() {
//1.获取验证码图片对象
var vcode = document.getElementById("vcode");
//2.设置其src属性,加时间戳
vcode.src = "${pageContext.request.contextPath}/checkCodeServlet?time=" + new Date().getTime();
}
</script>
<style type="text/css">
.login_div {
width: 500px;
margin: auto;
}
</style>
</head>
<body>
<div class="login_div">
<h3 style="..." align="center">用户登录</h3>
<form class="form-group" action="${pageContext.request.contextPath}/loginServlet" method="post">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" class="form-control" id="username" name="username" placeholder="请输入用户名">
</div>
<div class="form-group">
<label for="passowrd">密码</label>
<input type="password" class="form-control" id="passowrd" name="password" placeholder="请输入密码">
</div>
<div class="form-group">
<label for="verifycode">验证码</