目录
一、业务需求
实现用户登录和退出登录功能,要求一个用户只在一处登录。完成对用户表的CRUD操作。
主要以消化技术为主。
二、技术栈
JSP、Servlet、Filter、Listener、JDBC、MySQL
三、创建数据库表
CREATE TABLE `users` (
`userid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) DEFAULT NULL,
`userpwd` varchar(30) DEFAULT NULL,
`usersex` varchar(2) DEFAULT NULL,
`phonenumber` varchar(30) DEFAULT NULL,
`qqnumber` varchar(20) DEFAULT NULL,
PRIMARY KEY (`userid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
四、搭建环境
4.1 创建web项目
4.2 添加jar
用到数据库:MySQL驱动的jar
用到servlet:servlet-api.jar
页面中中使用jstl标签库:jstl标签库jar包
4.3 添加jstl标签库的约束文件
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
五、创建项目包以及工具类
5.1 创建项目包
5.2 创建POJO
package com.zj.pojo;
public class User {
private int userid;
private String username;
private String userpwd;
private String usersex;
private String phonenumber;
private String qqnumber;
public User() {
}
public User(int userid, String username, String userpwd, String usersex, String phonenumber, String qqnumber) {
this.userid = userid;
this.username = username;
this.userpwd = userpwd;
this.usersex = usersex;
this.phonenumber = phonenumber;
this.qqnumber = qqnumber;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpwd() {
return userpwd;
}
public void setUserpwd(String userpwd) {
this.userpwd = userpwd;
}
public String getUsersex() {
return usersex;
}
public void setUsersex(String usersex) {
this.usersex = usersex;
}
public String getPhonenumber() {
return phonenumber;
}
public void setPhonenumber(String phonenumber) {
this.phonenumber = phonenumber;
}
public String getQqnumber() {
return qqnumber;
}
public void setQqnumber(String qqnumber) {
this.qqnumber = qqnumber;
}
@Override
public String toString() {
return "User{" +
"userid=" + userid +
", username='" + username + '\'' +
", userpwd='" + userpwd + '\'' +
", usersex='" + usersex + '\'' +
", phonenumber='" + phonenumber + '\'' +
", qqnumber='" + qqnumber + '\'' +
'}';
}
}
5.3 创建JDBC工具类
在src下创建db.properties属性文件
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456
package com.zj.commons;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ResourceBundle;
public class jdbcUtils {
private static String driver;
private static String url;
private static String username;
private static String password;
//初始化数据库驱动,读取db.properties配置文件的信息(static中的资源只会加载一次)
static {
ResourceBundle resourceBundle = ResourceBundle.getBundle("db");
driver = resourceBundle.getString("jdbc.driver");
url = resourceBundle.getString("jdbc.url");
username = resourceBundle.getString("jdbc.username");
password = resourceBundle.getString("jdbc.password");
//加载数据库驱动
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection(){
Connection con = null;
try {
con = DriverManager.getConnection(url, username, password);
}catch (Exception e){
e.printStackTrace();
}
return con;
}
//关闭连接
public static void closeConnection(Connection con){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//事务回滚
public static void rollbackConnection(Connection con) {
try {
con.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
六、用户登录业务的实现
6.1 创建登录页面
将样式文件先复制到web目录下。
在web目录下创建login.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />
<title>欢迎登录后台管理系统</title>
<link href="css/style.css" rel="stylesheet" type="text/css" />
<script language="JavaScript" src="js/jquery.js"></script>
<script src="js/cloud.js" type="text/javascript"></script>
<script language="javascript">
if (window.parent.length>0){
window.parent.location = "login.jsp";
}
$(function(){
$('.loginbox').css({'position':'absolute','left':($(window).width
()-692)/2});
$(window).resize(function(){
$('.loginbox').css({'position':'absolute','left':($(window).width
()-692)/2});
})
});
/*点击验证码图片生成验证码*/
function change() {
$("#code").attr("src","ValidateCodeServlet.do?"+Math.random())
}
</script>
</head>
<body style="background-color:#1c77ac;
background-image:url(images/light.png);
background-repeat:no-repeat; background-position:center top;
overflow:hidden;">
<div id="mainBody">
<div id="cloud1" class="cloud"></div>
<div id="cloud2" class="cloud"></div>
</div>
<div class="logintop">
<ul>
<li><a href="#">回首页</a></li>
<li><a href="#">帮助</a></li>
<li><a href="#">关于</a></li>
</ul>
</div>
<div class="loginbody">
${requestScope.msg}
<div class="loginbox loginbox2">
<form action="login.do" method="post">
<ul>
<li><input name="username" type="text" class="loginuser" value="admin" onclick="JavaScript:this.value=''"/></li>
<li><input name="userpwd" type="password" class="loginpwd" value="" onclick="JavaScript:this.value=''"/></li>
<li class="yzm">
<span><input name="code" type="text" value="验证码" onclick="JavaScript:this.value=''"/></span><cite><img id="code" src="ValidateCodeServlet.do" onclick="change()"/></cite>
</li>
<li><input name="" type="submit" class="loginbtn" value="登录" onclick="javascript:window.location='main.html'"/></li>
</ul>
</form>
</div>
</div>
</body>
</html>
6.2 创建登录业务的持久层
在Dao包下创建UserLoginDao接口,在接口中创建抽象方法selectUserByUserNameAndPassword。
package com.zj.dao;
import com.zj.pojo.User;
public interface UserLoginDao {
public User selectUserByUserNameAndPassword(String userName, String password);
}
创建UserLoginDao接口的实现类UserLoginDaoImpl实现接口。
package com.zj.dao.impl;
import com.zj.commons.jdbcUtils;
import com.zj.dao.UserLoginDao;
import com.zj.pojo.User;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class UserLoginDaoImpl implements UserLoginDao {
/*用户登录实现*/
@Override
public User selectUserByUserNameAndPassword(String userName, String password) {
User user = null;
Connection conn = null;
try {
conn = jdbcUtils.getConnection();
PreparedStatement ps = conn.prepareStatement("select * from users where username = ? and userpwd = ?");
ps.setString(1, userName);
ps.setString(2, password);
ResultSet resultSet = ps.executeQuery();
while (resultSet.next()) {
user = new User();
user.setUsername(resultSet.getString("username"));
user.setUserpwd(resultSet.getString("userpwd"));
user.setUsersex(resultSet.getString("usersex"));
user.setPhonenumber(resultSet.getString("phonenumber"));
user.setQqnumber(resultSet.getString("qqnumber"));
}
}catch (Exception e) {
e.printStackTrace();
}
return user;
}
}
6.3 登录业务的业务层
在Service包下创建UserLoginService接口,在接口中创建抽象方法userLogin。
package com.zj.service;
import com.zj.pojo.User;
public interface UserLoginService {
public User userLogin(String username, String password);
}
创建UserLoginService接口的实现类UserLoginServiceImpl实现接口。
package com.zj.service.Impl;
import com.zj.dao.UserLoginDao;
import com.zj.dao.impl.UserLoginDaoImpl;
import com.zj.exception.UserNotFoundException;
import com.zj.pojo.User;
import com.zj.service.UserLoginService;
/*用户登录业务*/
public class UserLoginServiceImpl implements UserLoginService {
@Override
public User userLogin(String username, String password) {
//创建持久层对象
UserLoginDao userLoginDao = new UserLoginDaoImpl();
User user = userLoginDao.selectUserByUserNameAndPassword(username, password);
if (user == null) {
throw new UserNotFoundException("用户名或密码有误!");
}
return user;
}
}
同时创建异常类UserNotFoundException,当没有查到用户的信息的时候抛出异常,要继承RuntimeException 。
package com.zj.exception;
/*用户登录状态的自定义异常*/
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(){
}
public UserNotFoundException(String message) {
}
public UserNotFoundException(String message, Throwable cause) {
}
}
6.4 创建登录业务的web层
在servlet包下创建UserLoginServlet 。
package com.zj.web.servlet;
import com.zj.commons.Constants;
import com.zj.exception.UserNotFoundException;
import com.zj.pojo.User;
import com.zj.service.Impl.UserLoginServiceImpl;
import com.zj.service.UserLoginService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/*处理用户登录的请求*/
@WebServlet("/login.do")
public class UserLoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
try {
UserLoginService userLoginService = new UserLoginServiceImpl();
User user = userLoginService.userLogin(username, password);
//如果存在user,建立客户端和服务端的会话状态。
HttpSession session = req.getSession();
session.setAttribute(Constants.USER_SESSION_KEY,user);
//使用重定向跳转到首页,因为可以改变地址栏的地址
resp.sendRedirect("main.jsp");
}catch (UserNotFoundException e) {//这是我们关心的异常
//用户登陆失败跳转到登录页面
req.setAttribute("msg",e.getMessage());
req.getRequestDispatcher("login.jsp").forward(req,resp);
}catch (Exception e) { //处理异常的最后一道防线,处理其他异常
//出现其他错误
resp.sendRedirect("error.jsp");
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
在工具包创建Constants 抽象类(不能被实例化)存放常量。
package com.zj.commons;
/*常量抽象类,避免字符串硬编码。不允许被实例化*/
public abstract class Constants {
public static String USER_SESSION_KEY = "user";
}
在web目录下创建main.jsp,作为登录成功跳转的页面。其中main.jsp是由index.jsp、left.jsp、footer.jsp构成。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />
<title>信息管理系统界面</title>
</head>
<frameset rows="*,31" cols="*" frameborder="no" border="0"
framespacing="0">
<frameset cols="187,*" frameborder="no" border="0"
framespacing="0">
<frame src="left.jsp" name="leftFrame" scrolling="No"
noresize="noresize" id="leftFrame" title="leftFrame" />
<frame src="index.jsp" name="rightFrame" id="rightFrame"
title="rightFrame" />
</frameset>
<frame src="footer.jsp" name="bottomFrame" scrolling="No"
noresize="noresize" id="bottomFrame" title="bottomFrame" />
</frameset>
<noframes><body>
</body></noframes>
</html>
</html>
6.5 创建登录业务的Filter
创建UserLoginFilter实现未登录拦截。
package com.zj.web.filter;
import com.sun.org.apache.bcel.internal.Const;
import com.zj.commons.Constants;
import com.zj.pojo.User;
import jdk.nashorn.internal.objects.NativeArray;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import java.io.IOException;
/*判断当前客户端浏览器是否登录的Filter*/
@WebFilter("/*")
public class UserLoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String uri = request.getRequestURI();
//判断当前路径是否是login.jsp或者login.do,放行这两个资源,还需要放行验证码图片。
if (uri.indexOf("login.jsp") != -1 || uri.indexOf("login.do") != -1 || uri.indexOf("ValidateCodeServlet.do")!= -1) {
filterChain.doFilter(request,response);
}else {
HttpSession session = request.getSession();
User user = (User) session.getAttribute(Constants.USER_SESSION_KEY);
if (user != null) {
filterChain.doFilter(request,response);
}else {
request.setAttribute(Constants.REQUEST_MSG,"不登陆不好使!(⊙o⊙)?");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}
}
@Override
public void destroy() {
}
}
6.6 实现用户只能在一处登录
当前的一个账号可以在多个浏览器登录,我们要实现的是账号在另一个浏览器登陆的时候会挤掉当前浏览器的账户。
实现的原理是将当前用户的session放在context中缓存,用户在当前浏览器登录的时候首先查看context中是否存在当前用户的session信息,存在的话表示当前用户在其他浏览器已经登录过了,则删除该之前浏览器和服务端之间的会话session,重新建立当前浏览器与服务端的session连接,并将该session保存到context中。
6.7 解决HttpSession超时销毁时的异常问题
6.6实现了用户只能在一处登录,但是session有自动销毁的时间是半个小时。此时session被tomcat销毁但是context还保存着已经被销毁的session的信息,再使用另一个浏览器登陆时仍然能拿到这个被销毁的session,再一次销毁这个session的时候就会报错,因为之前已经被tomcat销毁了嘛。此时可以通过listener监听器来监听session的声明周期。
package com.zj.web.listener;
import com.zj.commons.Constants;
import com.zj.pojo.User;
import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class HttpSessionLifeListener implements HttpSessionListener {
/*HttpSession被销毁之前触发该方法*/
@Override
public void sessionDestroyed(HttpSessionEvent se) {
//获取servletContext对象,将保存在context中的即将被销毁的session删除。
HttpSession session = se.getSession();
ServletContext servletContext = session.getServletContext();
User user = (User) servletContext.getAttribute(Constants.USER_SESSION_KEY);
servletContext.removeAttribute(user.getUserid()+"");
}
}
6.8 在登录中添加验证码功能
首先将生成验证码的servlet工具类添加到项目中
package com.zj.commons;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet("/ValidateCodeServlet.do")
public class ValidateCodeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 在内存中创建图象
int width = 70, height = 45;
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// 获取图形上下文
Graphics g = image.getGraphics();
// 生成随机类
Random random = new Random();
// 设定背景色
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height);
// 设定字体
g.setFont(new Font("Times New Roman", Font.PLAIN, 20));
// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
g.setColor(getRandColor(160, 200));
for (int i = 0; i < 155; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x, y, x + xl, y + yl);
}
// 取随机产生的认证码(4位数字)
String sRand = "";
for (int i = 0; i < 4; i++) {
String rand = String.valueOf(random.nextInt(10));
sRand += rand;
// 将认证码显示到图象中
g.setColor(new Color(20 + random.nextInt(110), 20 + random
.nextInt(110), 20 + random.nextInt(110)));
// 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
g.drawString(rand, 13 * i + 6, 16);
}
// 图象生效
g.dispose();
try {
ImageIO.write(image, "JPEG", response.getOutputStream());
} catch (Exception e) {
System.out.println("验证码图片产生出现错误:" + e.toString());
}
//保存验证码到Session
request.getSession().setAttribute("randStr", sRand);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
/*
* 给定范围获得随机颜色
*/
private Color getRandColor(int fc, int bc) {
Random random = new Random();
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}
}
修改登录页面在login.jsp中添加验证码标签img,定义函数change每次点击验证码都会更换。
<img id="code" src="ValidateCodeServlet.do" onclick="change"/>
/*点击验证码图片生成验证码*/
function change() {
$("#code").attr("src","ValidateCodeServlet.do?"+Math.random())
}
在 UserLoginFilter过滤器中放行验证码图片资源。
if (uri.indexOf("login.jsp") != -1 || uri.indexOf("login.do") != -1 || uri.indexOf("ValidateCodeServlet.do")!= -1) {
filterChain.doFilter(request,response);
}
在UserLoginServlet中实现验证码的校验。
6.9 用户退出功能
在left.jsp页面添加退出功能的标签。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
</html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<link href="css/style.css" rel="stylesheet" type="text/css" />
<script language="JavaScript" src="js/jquery.js"></script>
<script type="text/javascript">
$(function(){
//导航切换
$(".menuson .header").click(function(){
var $parent = $(this).parent();
$(".menuson>li.active").not($parent).removeClass("active open").find('.sub-menus').hide();
$parent.addClass("active");
if(!!$(this).next('.sub-menus').size()){
if($parent.hasClass("open")){
$parent.removeClass("open").find('.sub-menus').hide();
}else{
$parent.addClass("open").find('.sub-menus').show();
}
}
});
// 三级菜单点击
$('.sub-menus li').click(function(e) {
$(".sub-menus li.active").removeClass("active")
$(this).addClass("active");
});
$('.title').click(function(){
var $ul = $(this).next('ul');
$('dd').find('.menuson').slideUp();
if($ul.is(':visible')){
$(this).next('.menuson').slideUp();
}else{
$(this).next('.menuson').slideDown();
}
});
})
</script>
</head>
<body style="background:#f0f9fd;">
<div class="lefttop"><span></span>导航菜单</div>
<dl class="leftmenu">
<dd>
<div class="title"><span><img src="images/leftico03.png" /></span>用户管理</div>
<ul class="menuson">
<li><cite></cite><a href="userAdd.jsp" target="rightFrame">添加用户</a><i></i></li>
<li><cite></cite><a href="findUser.jsp" target="rightFrame">查询用户</a><i></i></li>
<li><cite></cite><a href="logout.do" target="rightFrame">退出登录</a><i></i></li>
</ul>
</dd>
</dl>
</body>
</html>
创建用户退出登录的servlet
package com.zj.web.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/*用户退出*/
@WebServlet("/logout.do")
public class LogoutServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
//因为配置了监听器,在session销毁的时候会调用监听器的方法,删除context中的session
session.invalidate();
//重定向到登录页面
resp.sendRedirect("login.jsp");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
七、添加用户业务
7.1 创建添加用户持久层
创建接口和实现类
package com.zj.dao;
import com.zj.pojo.User;
public interface UserManageDao {
//用户添加
void insertUser(User user);
}
package com.zj.dao.impl;
import com.zj.commons.jdbcUtils;
import com.zj.dao.UserManageDao;
import com.zj.pojo.User;
import java.sql.Connection;
import java.sql.PreparedStatement;
public class UserManageDaoImpl implements UserManageDao {
@Override
public void insertUser(User user) {
Connection con = null;
try {
con = jdbcUtils.getConnection();
//关闭自动提交事务,加深对事务印象
con.setAutoCommit(false);
PreparedStatement ps = con.prepareStatement("INSERT INTO users values (default ,?,?,?,?,?)");
ps.setString(1, user.getUsername());
ps.setString(2, user.getUserpwd());
ps.setString(3, user.getUsersex());
ps.setString(4, user.getPhonenumber());
ps.setString(5, user.getQqnumber());
ps.executeUpdate();
con.commit();
}catch (Exception e) {
e.printStackTrace();
//出现异常回滚
jdbcUtils.rollbackConnection(con);
}finally {
jdbcUtils.closeConnection(con);
}
}
}
7.2 创建添加用户业务层
创建添加用户的接口和实现类
package com.zj.service;
import com.zj.pojo.User;
public interface UserManageService {
void addUser(User user);
}
package com.zj.service.Impl;
import com.zj.dao.UserManageDao;
import com.zj.dao.impl.UserManageDaoImpl;
import com.zj.pojo.User;
import com.zj.service.UserManageService;
public class UserManageServiceImpl implements UserManageService {
/*添加用户*/
@Override
public void addUser(User user) {
UserManageDao userManageDao = new UserManageDaoImpl();
userManageDao.insertUser(user);
}
}
7.3 创建添加用户servlet
package com.zj.web.servlet;
import com.zj.pojo.User;
import com.zj.service.Impl.UserManageServiceImpl;
import com.zj.service.UserManageService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/userManage.do")
public class UserManageServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String flag = req.getParameter("flag");
if ("add".equals(flag)) {
addUser(req, resp);
}
}
//添加用户
private void addUser(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
User user = this.createUser(request, response);
try {
UserManageService userManagerService = new UserManageServiceImpl();
userManagerService.addUser(user);
response.sendRedirect("ok.jsp"); //重定向防止数据重复提交
}catch (Exception e) {
e.printStackTrace();
response.sendRedirect("error.jsp");
}
}
//获取用户提交的数据
private User createUser(HttpServletRequest request,HttpServletResponse response){
String username = request.getParameter("username");
String userpwd = request.getParameter("userpwd");
String usersex = request.getParameter("usersex");
String phonenumber = request.getParameter("phonenumber");
String qqnumber = request.getParameter("qqnumber");
User user = new User(0,username, userpwd, usersex, phonenumber, qqnumber);
return user;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
7.4 创建添加用户页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<link href="../css/style.css" rel="stylesheet" type="text/css" />
<link href="../css/style.css" rel="stylesheet" type="text/css" />
<link href="../css/select.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="../js/jquery.js"></script>
<script type="text/javascript" src="../js/jquery.idTabs.min.js"></script>
<script type="text/javascript" src="../js/select-ui.min.js"></script>
<script type="text/javascript" src="editor/kindeditor.js"></script>
<script type="text/javascript" src="My97DatePicker/WdatePicker.js"></script>
<script type="text/javascript">
$(document).ready(function(e) {
$(".select1").uedSelect({
width : 345
});
});
function save(){
window.location='ok.html';
}
</script>
<script type="text/javascript">
KE.show({id:"ecp",width:"800px",height:"300px"});
</script>
</head>
<body>
<div class="place">
<span>位置:</span>
<ul class="placeul">
<li><a href="#">用户管理</a></li>
<li><a href="#">添加用户</a></li>
</ul>
</div>
<div class="formbody">
<div class="formtitle"><span>添加用户</span></div>
<form action="../userManage.do" method="post">
<%--当前是添加用户信息--%>
<input type="hidden" name="flag" value="add"/>
<ul class="forminfo">
<li>
<label>用户名</label>
<input name="username" type="text" class="dfinput" /></li>
<li>
<li>
<label>用户密码</label>
<input name="userpwd" type="text" class="dfinput" /><i></i></li>
<li>
<label>性别</label>
<input name="usersex" type="radio" value="1" checked="checked" />男
<input name="usersex" type="radio" value="0" />女
</li>
<li>
<label>联系方式</label>
<input name="phonenumber" type="text" class="dfinput" />
</li>
<li>
<label>QQ号</label>
<input name="qqnumber" type="text" class="dfinput" />
</li>
<li>
<label> </label>
<input type="submit" class="btn" value="确认保存" />
</li>
</ul>
</form>
</div>
</body>
</html>
创建添加成功的页面ok.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<link href="css/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
function submitForm(){
window.close();
}
</script>
</head>
<body>
<div class="place">
<span>位置:</span>
<ul class="placeul">
<li><a href="#">操作提示</a></li>
</ul>
</div>
操作成功!
</body>
</html>
八、查询用户业务
8.1 创建查询用户持久层
创建查询用户的抽象方法和实现类。
package com.zj.dao;
import com.zj.pojo.User;
import java.util.List;
public interface UserManageDao {
//用户添加
void insertUser(User user);
//查询用户
List<User> selectUserByProperty(User user);
}
package com.zj.dao.impl;
import com.zj.commons.jdbcUtils;
import com.zj.dao.UserManageDao;
import com.zj.pojo.User;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class UserManageDaoImpl implements UserManageDao {
@Override
public void insertUser(User user) {
Connection con = null;
try {
con = jdbcUtils.getConnection();
//关闭自动提交事务,加深对事务印象
con.setAutoCommit(false);
PreparedStatement ps = con.prepareStatement("INSERT INTO users values (default ,?,?,?,?,?)");
ps.setString(1, user.getUsername());
ps.setString(2, user.getUserpwd());
ps.setString(3, user.getUsersex());
ps.setString(4, user.getPhonenumber());
ps.setString(5, user.getQqnumber());
ps.executeUpdate();
con.commit();
}catch (Exception e) {
e.printStackTrace();
//出现异常回滚
jdbcUtils.rollbackConnection(con);
}finally {
jdbcUtils.closeConnection(con);
}
}
@Override
public List<User> selectUserByProperty(User user) {
Connection con = null;
List<User> users = new ArrayList<User>();
try {
con = jdbcUtils.getConnection();
String sql = this.createSQL(user);
PreparedStatement ps = con.prepareStatement(sql);
ResultSet resultSet = ps.executeQuery();
while (resultSet.next()) {
User u = new User();
u.setUserid(resultSet.getInt("userid"));
u.setUsername(resultSet.getString("username"));
u.setPhonenumber(resultSet.getString("phonenumber"));
u.setQqnumber(resultSet.getString("qqnumber"));
u.setUserpwd(resultSet.getString("userpwd"));
u.setUsersex(resultSet.getString("usersex"));
users.add(u);
}
}catch (Exception e) {
e.printStackTrace();
}
return users;
}
//sql拼接
private String createSQL(User user){
//没有给定查询参数时,查询全部数据
StringBuffer stringBuffer = new StringBuffer("select * from users where 1=1");
if (user.getUsersex() !=null && user.getUsersex().length() > 0){//从表单获取的数据是空串,也是有长度的。所以还要判断当前的字段的长度。
//拼接到sql
stringBuffer.append(" and usersex="+user.getUsersex());
}
if (user.getQqnumber() !=null && user.getQqnumber().length()>0){
stringBuffer.append(" and qqnumber="+user.getQqnumber());
}
if (user.getUsername() !=null && user.getUsername().length()>0){
stringBuffer.append(" and username="+user.getUsername());
}
if (user.getPhonenumber() !=null && user.getPhonenumber().length()>0){
stringBuffer.append(" and phonenumber="+user.getPhonenumber());
}
return stringBuffer.toString();
}
}
8.2 创建查询用户的业务层
package com.zj.service;
import com.zj.pojo.User;
import java.util.List;
public interface UserManageService {
void addUser(User user);
List<User> findUsers(User user);
}
package com.zj.service.Impl;
import com.zj.dao.UserManageDao;
import com.zj.dao.impl.UserManageDaoImpl;
import com.zj.pojo.User;
import com.zj.service.UserManageService;
import java.util.List;
public class UserManageServiceImpl implements UserManageService {
/*添加用户*/
@Override
public void addUser(User user) {
UserManageDao userManageDao = new UserManageDaoImpl();
userManageDao.insertUser(user);
}
/*查询用户*/
@Override
public List<User> findUsers(User user) {
UserManageDao userManageDao = new UserManageDaoImpl();
List<User> users = userManageDao.selectUserByProperty(user);
return users;
}
}
8.3 创建查询用户的servlet
/*处理查询用户请求*/
private void findUsers(HttpServletRequest request,HttpServletResponse response) throws IOException {
//获取用户请求的数据
User user = this.createUser(request, response);
try {
UserManageService userManageService = new UserManageServiceImpl();
List<User> users = userManageService.findUsers(user);
request.setAttribute("list",users);
request.getRequestDispatcher("usermanage/showUsers.jsp").forward(request, response);
}catch (Exception e){
e.printStackTrace();
response.sendRedirect("error.jsp");
}
}
8.4 创建查询用户与显示结果的页面
查询用户页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<link href="../css/style.css" rel="stylesheet" type="text/css" />
<link href="../css/select.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="place">
<span>位置:</span>
<ul class="placeul">
<li><a href="#">用户管理</a></li>
<li><a href="#">查询用户</a></li>
</ul>
</div>
<div class="rightinfo">
<form method="post" action="../userManage.do">
<input type="hidden" name="flag" value="find"/>
<ul class="prosearch">
<li>
<label>查询:</label>
<i>用户名</i>
<a>
<input name="username" type="text" class="scinput" />
</a>
</li>
<li>
<label>性别:</label>
<input name="usersex" type="radio" value="1" checked="checked" /> 男
<input name="usersex" type="radio" value="0" /> 女
</li>
<li>
<label>手机号:</label>
<a>
<input name="phonenumber" type="text" class="scinput" />
</a>
</li>
<li>
<label>QQ号:</label>
<a>
<input name="qqnumber" type="text" class="scinput" />
</a>
</li>
<a>
<input type="submit" class="sure" value="查询"/>
</a>
</ul>
</form>
</div>
</body>
</html>
显示结果页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>显示用户数据</title>
<%--当前页面是服务端跳转的页面不需要在样式文件加../--%>
<link href="css/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="place">
<span>位置:</span>
<ul class="placeul">
<li><a href="#">用户管理</a></li>
<li><a href="#">查询用户</a></li>
<li><a href="#">查询结果</a></li>
</ul>
</div>
<div class="rightinfo">
<div class="formtitle1"><span>用户列表</span></div>
<table class="tablelist" >
<thead>
<tr>
<th>序号</th>
<th>用户名</th>
<th>用户性别</th>
<th>手机号</th>
<th>QQ号</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach var="user" items="${requestScope.list}" varStatus="status">
<tr>
<td>${status.count}</td>
<td>${user.username}</td>
<td>
<c:choose>
<c:when test="${user.usersex == 1}">男</c:when>
<c:otherwise>女</c:otherwise>
</c:choose>
</td>
<td>${user.phonenumber}</td>
<td>${user.qqnumber}</td>
<td><a href="userUpdate.html" class="tablelink">修改</a> <a href="#" class="tablelink click"> 删除</a></td>
</tr>
</c:forEach>
</tbody>
</table>
<div class="tip">
<div class="tiptop"><span>提示信息</span><a></a></div>
<div class="tipinfo">
<span><img src="images/ticon.png" /></span>
<div class="tipright">
<p>是否确认对信息的修改 ?</p>
<cite>如果是请点击确定按钮 ,否则请点取消。</cite>
</div>
</div>
<div class="tipbtn">
<input name="" type="button" class="sure" value="确定" />
<input name="" type="button" class="cancel" value="取消" />
</div>
</div>
</div>
<script type="text/javascript">
$('.tablelist tbody tr:odd').addClass('odd');
</script>
</body>
</html>
九、更新用户业务
9.1 创建预更新用户查询的持久层接口和实现类
package com.zj.dao;
import com.zj.pojo.User;
import java.util.List;
public interface UserManageDao {
//用户添加
void insertUser(User user);
//查询用户
List<User> selectUserByProperty(User user);
//更新用户
User selectUserById(int userid);
}
//根据id查询用户数据
@Override
public User selectUserById(int userid) {
Connection con = null;
User u = null;
try {
con = jdbcUtils.getConnection();
PreparedStatement ps = con.prepareStatement("select * from users where userid = ?");
ps.setInt(1, userid);
ResultSet resultSet = ps.executeQuery();
while (resultSet.next()) {
u = new User();
u.setUserid(resultSet.getInt("userid"));
u.setUsername(resultSet.getString("username"));
u.setPhonenumber(resultSet.getString("phonenumber"));
u.setQqnumber(resultSet.getString("qqnumber"));
u.setUserpwd(resultSet.getString("userpwd"));
u.setUsersex(resultSet.getString("usersex"));
}
}catch (Exception e){
e.printStackTrace();
}finally {
jdbcUtils.closeConnection(con);
}
return u;
}
9.2 创建预更新用户的业务层
package com.zj.service;
import com.zj.pojo.User;
import java.util.List;
public interface UserManageService {
void addUser(User user);
List<User> findUsers(User user);
User findUserById(int id);
}
/*根据用户id查询用户,预更新用户*/
@Override
public User findUserById(int id) {
UserManageDao userManageDao = new UserManageDaoImpl();
User user = userManageDao.selectUserById(id);
return user;
}
9.3 创建更新预查询的servlet
//用户预更新查询
public void preUpdate(HttpServletRequest request, HttpServletResponse response) throws IOException {
String userid = request.getParameter("userid");
try {
UserManageService userService = new UserManageServiceImpl();
User user = userService.findUserById(Integer.parseInt(userid));
request.setAttribute("user", user);
request.getRequestDispatcher("usermanage/update.jsp").forward(request, response);
}catch (Exception e){
e.printStackTrace();
response.sendRedirect("error.jsp");
}
}
9.4 创建更新用户页面
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<link href="css/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
function update(){
window.location='ok.html';
}
</script>
</head>
<body>
<div class="place">
<span>位置:</span>
<ul class="placeul">
<li><a href="#">用户管理</a></li>
<li><a href="#">修改用户</a></li>
</ul>
</div>
<div class="formbody">
<div class="formtitle"><span>基本信息</span></div>
<form method="post" action="../userManage.do">
<ul class="forminfo">
<li><label>用户名</label><input name="username" type="text" class="dfinput" value="${requestScope.user.username}"/> </li>
<li>
<label>性别</label>
<c:choose>
<c:when test="${requestScope.user.usersex == 1}">
<input name="usersex" type="radio" value="1" checked="checked" />男
<input name="usersex" type="radio" value="0" />女
</c:when>
<c:otherwise>
<input name="usersex" type="radio" value="1" />男
<input name="usersex" type="radio" value="0" checked="checked"/>女
</c:otherwise>
</c:choose>
</li>
<li><label>手机号</label><input name="phonenumber" type="text" class="dfinput" value="${requestScope.user.phonenumber}"/></li>
<li><label>QQ号</label><input name="qqnumber" type="text" class="dfinput" value="${requestScope.user.qqnumber}"/></li>
<li><label> </label><input type="submit" class="btn" value="确认修改"/></li>
</ul>
</form>
</div>
</body>
</html>
9.5 创建更新用户持久层
package com.zj.dao;
import com.zj.pojo.User;
import java.util.List;
public interface UserManageDao {
//用户添加
void insertUser(User user);
//查询用户
List<User> selectUserByProperty(User user);
//预更新用户
User selectUserById(int userid);
//更新用户
void updateUser(User user);
}
@Override
public void updateUser(User user) {
Connection con = null;
try {
con = jdbcUtils.getConnection();
con.setAutoCommit(false);
PreparedStatement ps = con.prepareStatement("update users set userpwd=?, username=?,usersex=?,phonenumber=?,qqnumber=?");
ps.setString(1, user.getUserpwd());
ps.setString(2,user.getUsername());
ps.setString(3,user.getUsersex());
ps.setString(4, user.getPhonenumber());
ps.setString(5, user.getQqnumber());
int i = ps.executeUpdate();
con.commit();
}catch (Exception e){
e.printStackTrace();
jdbcUtils.rollbackConnection(con);
}finally {
jdbcUtils.closeConnection(con);
}
}
9.6 创建更新用户业务层
package com.zj.service;
import com.zj.pojo.User;
import java.util.List;
public interface UserManageService {
void addUser(User user);
List<User> findUsers(User user);
User findUserById(int id);
void modifyUser(User user);
}
/*修改用户*/
@Override
public void modifyUser(User user) {
UserManageDao userManageDao = new UserManageDaoImpl();
userManageDao.updateUser(user);
}
9.7 创建更新用户Servlet
/*更新用户*/
public void modifyUser(HttpServletRequest request, HttpServletResponse response) throws IOException {
User user = this.createUser(request, response);
try {
UserManageService userService = new UserManageServiceImpl();
userService.modifyUser(user);
response.sendRedirect("ok.jsp");
}catch (Exception e) {
e.printStackTrace();
response.sendRedirect("error.jsp");
}
}
9.8 修改更新用户页面完成用户更新
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<link href="css/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
function update(){
window.location='ok.html';
}
</script>
</head>
<body>
<div class="place">
<span>位置:</span>
<ul class="placeul">
<li><a href="#">用户管理</a></li>
<li><a href="#">修改用户</a></li>
</ul>
</div>
<div class="formbody">
<div class="formtitle"><span>基本信息</span></div>
<%--从servlet跳转过来的不需要加../--%>
<form method="post" action="userManage.do">
<input type="hidden" name="flag" value="modify">
<input type="hidden" name="userid" value="${requestScope.user.userid}">
<ul class="forminfo">
<li><label>用户名</label><input name="username" type="text" class="dfinput" value="${requestScope.user.username}"/> </li>
<li>
<label>性别</label>
<c:choose>
<c:when test="${requestScope.user.usersex == 1}">
<input name="usersex" type="radio" value="1" checked="checked" />男
<input name="usersex" type="radio" value="0" />女
</c:when>
<c:otherwise>
<input name="usersex" type="radio" value="1" />男
<input name="usersex" type="radio" value="0" checked="checked"/>女
</c:otherwise>
</c:choose>
</li>
<li><label>手机号</label><input name="phonenumber" type="text" class="dfinput" value="${requestScope.user.phonenumber}"/></li>
<li><label>QQ号</label><input name="qqnumber" type="text" class="dfinput" value="${requestScope.user.qqnumber}"/></li>
<li><label> </label><input type="submit" class="btn" value="确认修改"/></li>
</ul>
</form>
</div>
</body>
</html>
十、删除用户业务
10.1 创建删除用户持久层
package com.zj.dao;
import com.zj.pojo.User;
import java.util.List;
public interface UserManageDao {
//用户添加
void insertUser(User user);
//查询用户
List<User> selectUserByProperty(User user);
//预更新用户
User selectUserById(int userid);
//更新用户
void updateUser(User user);
/*删除用户*/
void deleteUserById(int userid);
}
// 根据用户id删除用户
@Override
public void deleteUserById(int userid) {
Connection con = null;
try {
con = jdbcUtils.getConnection();
con.setAutoCommit(false);
PreparedStatement ps = con.prepareStatement("DELETE FROM users where userid = ? ");
ps.setInt(1,userid);
ps.executeUpdate();
con.commit();
}catch (Exception e) {
e.printStackTrace();
jdbcUtils.rollbackConnection(con);
}finally {
jdbcUtils.closeConnection(con);
}
}
10.2 创建删除用户业务层
package com.zj.service;
import com.zj.pojo.User;
import java.util.List;
public interface UserManageService {
void addUser(User user);
List<User> findUsers(User user);
User findUserById(int id);
void modifyUser(User user);
void removeUser(int userid);
}
/*删除用户*/
@Override
public void removeUser(int userid) {
UserManageDao userManageDao = new UserManageDaoImpl();
userManageDao.deleteUserById(userid);
}
10.3 创建删除用户Servlet
/*删除用户*/
private void removeUser(HttpServletRequest request, HttpServletResponse response) throws IOException{
String userid = request.getParameter("userid");
try {
UserManageService userService = new UserManageServiceImpl();
userService.removeUser(Integer.parseInt(userid));
response.sendRedirect("ok.jsp");
}catch (Exception e) {
e.printStackTrace();
response.sendRedirect("error.jsp");
}
}
10.4 修改showUsers.jsp页面完成用户删除
<%--超链接直接发送请求不需要加../--%>
<td><a href="userManage.do?flag=preUpdate&userid=${user.userid}" class="tablelink">修改</a> <a href="userManage.do?userid=${requestScope.user.userid}" class="tablelink click"> 删除</a></td>