github地址:zljr/userManage: 注册和登录页面,使用servlet+jsp+ajax+过滤器+fastjson实现 (github.com)
准备工作:建好下面这些包,dao(跟数据库相关操作),entity(实体类),filter(过滤器),service(对dao里的进行封装),servlet(发送http请求),utils(工具类),libs(依赖包)
新建config.properties文件(位于src目录下),用于配置与mysql数据库连接。
新建JdbcUtil.java,位于utils目录下,用于实现数据库连接配置。
package cn.edu.zuel.utils; import java.io.InputStream; import java.sql.*; import java.util.Properties; public class JdbcUtil { private static String driverClass; private static String url; private static String user; private static String password; static{ try { InputStream resourceAsStream = JdbcUtil.class.getClassLoader().getResourceAsStream("config.properties"); Properties properties = new Properties(); properties.load(resourceAsStream); driverClass=properties.getProperty("driverClass"); url=properties.getProperty("url"); user=properties.getProperty("user"); password=properties.getProperty("password"); Class.forName(driverClass); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection(){ try{ return DriverManager.getConnection(url,user,password); }catch (Exception e){ e.printStackTrace(); return null; } } public static void closeConnection(ResultSet resultSet,Statement statement, Connection connection){ try{ if(resultSet!=null){ resultSet.close(); } if(statement!=null){ statement.close(); } if(connection!=null){ connection.close(); } }catch (Exception e){ e.printStackTrace(); } } public static void closeConnection(Statement statement,Connection connection){ closeConnection(null,statement,connection); } public static void beginTransaction(Connection conn){//开始事务 try{ conn.setAutoCommit(false); }catch (SQLException e){ throw new RuntimeException(e); } } public static void endTransaction(Connection conn){//结束事务 try{ conn.setAutoCommit(true); }catch (SQLException e){ throw new RuntimeException(e); } } public static void rollback(Connection conn){//回滚事务 try{ if(conn!=null){ conn.rollback(); } }catch (Exception e){ e.printStackTrace(); } } public static void commit(Connection conn){//提交事务 try{ if(conn!=null){ conn.commit(); } }catch (Exception e){ e.printStackTrace(); } } }
新建User实体类。
package cn.edu.zuel.entity; public class User { private String username; private String password; public User(String username, String password) { this.username = username; this.password = password; } public User() { } public String getUsername() { return username; } public String getPassword() { return password; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } }
新建UserDao,位于dao目录下
package cn.edu.zuel.dao; import cn.edu.zuel.entity.User; import cn.edu.zuel.utils.JdbcUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; public class UserDao { public User login(User user){ Connection conn=null; PreparedStatement stat=null; ResultSet resultSet=null; try{ conn= JdbcUtil.getConnection(); String sql="select *from user where username=? and password=?"; stat=conn.prepareStatement(sql); stat.setString(1,user.getUsername()); stat.setString(2,user.getPassword()); resultSet=stat.executeQuery(); if(resultSet.next()){ String username=resultSet.getString("username"); String password=resultSet.getString("password"); User user1=new User(username,password); return user1; } return null; }catch (Exception e){ e.printStackTrace(); return null; }finally { JdbcUtil.closeConnection(resultSet,stat,conn); } } public int register(User user){ Connection conn=null; PreparedStatement stat=null; try{ conn=JdbcUtil.getConnection(); JdbcUtil.beginTransaction(conn); String sql="insert into user values(?,?)"; stat=conn.prepareStatement(sql); stat.setString(1, user.getUsername()); stat.setString(2, user.getPassword()); int i = stat.executeUpdate(); conn.commit(); return i; }catch (Exception e){ e.printStackTrace(); JdbcUtil.rollback(conn); return 0; }finally { JdbcUtil.closeConnection(stat,conn); } } public User findByUsername(String username){ Connection conn=null; PreparedStatement stat=null; ResultSet resultSet=null; try{ conn= JdbcUtil.getConnection(); String sql="select *from user where username=?"; stat=conn.prepareStatement(sql); stat.setString(1,username); resultSet=stat.executeQuery(); if(resultSet.next()){ String password=resultSet.getString("password"); User user1=new User(username,password); return user1; } return null; }catch (Exception e){ e.printStackTrace(); return null; }finally { JdbcUtil.closeConnection(resultSet,stat,conn); } } }
新建UserService类,封装UserDao。
package cn.edu.zuel.service; import cn.edu.zuel.dao.UserDao; import cn.edu.zuel.entity.User; public class UserService { private UserDao userDao=new UserDao(); public User login(User user){ return userDao.login(user); } public int register(User user){return userDao.register(user);} public User findByUsername(String username){return userDao.findByUsername(username);} }
新建UserAjaxRegister.java,位于servlet目录下,用于实现有ajax的用户注册页面,涉及到验证码。
package cn.edu.zuel.servlet; import cn.edu.zuel.entity.User; import cn.edu.zuel.service.UserService; import com.alibaba.fastjson.JSONObject; import org.apache.commons.lang3.StringUtils; 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; import java.io.PrintWriter; import java.util.HashMap; @WebServlet("/userAjaxRegister") public class UserAjaxRegister extends HttpServlet { private UserService userService=new UserService(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=UTF-8"); // req.getRequestDispatcher("ajaxRegister.jsp").forward(req,resp); doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=UTF-8"); PrintWriter writer = resp.getWriter(); String username = req.getParameter("username"); String password = req.getParameter("password"); if(StringUtils.isEmpty(username)){ // req.setAttribute("errorMsg","用户名为空"); // req.getRequestDispatcher("register.jsp").forward(req,resp); // return; setResultError("用户名不能为空",writer); return; } if(StringUtils.isEmpty(password)){ // req.setAttribute("errorMsg","密码为空"); // req.getRequestDispatcher("register.jsp").forward(req,resp); setResultError("密码不能为空",writer); return; } if(userService.findByUsername(username)!=null){ // req.setAttribute("errorMsg","该用户"+username+"已经被注册!"); // req.getRequestDispatcher("register.jsp").forward(req,resp); setResultError("该用户"+username+"已被注册",writer); return; } User user = new User(); user.setUsername(username); user.setPassword(password); int register = userService.register(user); if(register<1){ // req.setAttribute("errorMsg","注册失败"); // req.getRequestDispatcher("register.jsp").forward(req,resp); setResultError("注册失败",writer); return; } String userCode=req.getParameter("checkCode"); HttpSession session=req.getSession(); String checkCodeO =(String)session.getAttribute("checkCodeO"); if(StringUtils.isEmpty(checkCodeO)){ setResultError("请加载图像验证码",writer); // 这一步相当重要,不然做接口测试注册时会出问题 return; } if (!checkCodeO.equalsIgnoreCase(userCode)) { // req.setAttribute("errorMsg","验证码错误"); // req.getRequestDispatcher("register.jsp").forward(req,resp); setResultError("验证码错误",writer); return; } setResultOk("注册成功",writer); // resp.sendRedirect("login.jsp"); } public void setResult(Integer code,String msg,PrintWriter writer){ HashMap<String, Object> result = new HashMap<>(); result.put("code",code); result.put("msg",msg); String jsonString = JSONObject.toJSONString(result); writer.print(jsonString); writer.close(); } public void setResultError(String msg,PrintWriter writer){ setResult(500,msg,writer); } public void setResultOk(String msg,PrintWriter writer){ setResult(200,msg,writer); } }
验证码工具类(可以留着用):
package cn.edu.zuel.utils; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; import java.util.Random; import javax.imageio.ImageIO; public class VerifyCode { private int w = 70; private int h = 35; private Random r = new Random(); // 定义有那些字体 private String[] fontNames = { "宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312" }; // 定义有那些验证码的随机字符,去掉易混的字符 private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ"; // 生成背景色 private Color bgColor = new Color(0,0,0); // 用于gettext 方法 获得生成的验证码文本 private String text; // 生成随机颜色 private Color randomColor() { int red = r.nextInt(150); int green = r.nextInt(150); int blue = r.nextInt(150); return new Color(red, green, blue); } // 生成随机字体 private Font randomFont() { int index = r.nextInt(fontNames.length); String fontName = fontNames[index]; int style = r.nextInt(4); int size = r.nextInt(5) + 24; return new Font(fontName, style, size); } // 画干扰线 private void drawLine(BufferedImage image) { int num = 3; Graphics2D g2 = (Graphics2D) image.getGraphics(); for (int i = 0; i < num; i++) { int x1 = r.nextInt(w); int y1 = r.nextInt(h); int x2 = r.nextInt(w); int y2 = r.nextInt(h); g2.setStroke(new BasicStroke(1.5F));// 不知道 g2.setColor(Color.BLUE); g2.drawLine(x1, y1, x2, y2); } } // 得到codes的长度内的随机数 并使用charAt 取得随机数位置上的codes中的字符 private char randomChar() { int index = r.nextInt(codes.length()); return codes.charAt(index); } // 创建一张验证码的图片 public BufferedImage createImage() { BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = (Graphics2D) image.getGraphics(); // 设置背景颜色 g2.setColor(bgColor); g2.fillRect(0, 0, w, h); StringBuilder sb = new StringBuilder(); // 向图中画四个字符 for (int i = 0; i < 4; i++) { String s = randomChar() + ""; sb.append(s); float x = i * 1.0F * w / 4; g2.setFont(randomFont()); g2.setColor(randomColor()); g2.drawString(s, x, h - 5); } this.text = sb.toString(); drawLine(image); // 返回图片 return image; } // 得到验证码的文本 后面是用来和用户输入的验证码 检测用 public String getText() { return text; } // 定义输出的对象和输出的方向 public static void output(BufferedImage bi, OutputStream fos) throws FileNotFoundException, IOException { ImageIO.write(bi, "JPEG", fos); } }
过滤器类:
package cn.edu.zuel.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @WebFilter("/*") public class UserSessionFilter implements Filter { private String []excludeUrls=new String[]{"/login","/register","/verifyCodeServlet","/existUserName","/userAjaxRegister","/ajaxRegister.jsp"}; @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest servletRequest1 = (HttpServletRequest) servletRequest; HttpServletResponse servletResponse1 = (HttpServletResponse) servletResponse; String contextPath = servletRequest1.getContextPath(); for(int i=0;i<excludeUrls.length;i++){ String excludeUrl=contextPath+excludeUrls[i]; String URI=servletRequest1.getRequestURI(); if(excludeUrl.equals(URI)){ filterChain.doFilter(servletRequest1,servletResponse1); return; } } HttpSession session = servletRequest1.getSession(); Object user=session.getAttribute("user"); if(user==null){ servletResponse1.sendRedirect("login"); return; } filterChain.doFilter(servletRequest1,servletResponse1); } @Override public void destroy() { } }
验证码servlet:
package cn.edu.zuel.servlet; import cn.edu.zuel.utils.VerifyCode; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; 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.awt.image.BufferedImage; import java.io.BufferedOutputStream; import java.io.IOException; @WebServlet("/verifyCodeServlet") public class VerifyCodeServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletOutputStream outputStream = resp.getOutputStream(); //通过resp的outputStream获取字节输出流 VerifyCode code = new VerifyCode(); BufferedImage image=code.createImage(); //创建验证码图像 ImageIO.write(image,"jpg",outputStream); //将图像保存到字节输出流中 String checkCode=code.getText(); //获取验证码文本 HttpSession session=req.getSession(); session.setAttribute("checkCodeO",checkCode); } } 用户登录servlet
package cn.edu.zuel.servlet; import cn.edu.zuel.entity.User; import cn.edu.zuel.service.UserService; import org.apache.commons.lang3.StringUtils; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/login") public class UserLogin extends HttpServlet { private UserService userService=new UserService(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=UTF-8"); req.getRequestDispatcher("login.jsp").forward(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=UTF-8"); String username=req.getParameter("username"); String password=req.getParameter("password"); if(StringUtils.isEmpty(username)){ req.setAttribute("errorMsg","用户名为空"); req.getRequestDispatcher("error.jsp").forward(req,resp); return; } if(StringUtils.isEmpty(password)){ req.setAttribute("errorMsg","密码为空"); req.getRequestDispatcher("error.jsp").forward(req,resp); return; } User user = new User(); user.setUsername(username); user.setPassword(password); User login = userService.login(user); if(login==null){ req.setAttribute("errorMsg","账号或密码错误"); req.getRequestDispatcher("login.jsp").forward(req,resp); return; } String rememberPassword = req.getParameter("rememberPassword"); if("on".equals(rememberPassword)){ Cookie username1 = new Cookie("username",username); username1.setMaxAge(60*60); Cookie password1 = new Cookie("password",password); password1.setMaxAge(60*60); resp.addCookie(username1); resp.addCookie(password1); } HttpSession session = req.getSession(); session.setAttribute("user",user); // req.getRequestDispatcher("success.jsp").forward(req,resp); resp.sendRedirect("index.jsp"); } }
判断用户是否存在Servlet,用于注册页面:
package cn.edu.zuel.servlet; import cn.edu.zuel.service.UserService; 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; import java.io.PrintWriter; @WebServlet("/existUserName") //实现输入姓名后,判断该用户名是否存在 public class ExistUserName extends HttpServlet { private UserService userService=new UserService(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=utf-8"); String username=req.getParameter("username"); PrintWriter writer = resp.getWriter(); if(userService.findByUsername(username)!=null){ writer.print("该用户"+username+"已经存在!"); } writer.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
前端:
ajaxRegister.jsp
<%-- Created by IntelliJ IDEA. User: 浙李鞠人 Date: 2024/8/8 Time: 14:37 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>ajax用户注册</title> </head> <body> <h1>用户注册</h1> <%--<form action="register" method="post">--%> <label>账 号:</label><input type="text" id="username" name="username" οnkeyup="existUsername(this)" ><br> <lable>密 码:</lable><input type="password" id="password" name="password"><br> <label>验 证码:</label><input typr="text" name="checkCode" id="checkCode"><br> <img id="checkCodeImg" src="verifyCodeServlet"> <a href="#" id="changeImg">看不清?换一个</a> <script> document.getElementById("changeImg").οnclick=function (){ document.getElementById("checkCodeImg").src="verifyCodeServlet?"+new Date().getMilliseconds(); } </script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script> function existUsername(object){ var username=object.value; axios({ method:"GET", url:"http://localhost:8080${pageContext.request.contextPath}/existUserName", params:{ username:username, } }).then(function (result){ document.getElementById("error").innerText=result.data; }) } </script> <script> function ajaxRegister(){ var username=document.getElementById("username").value; var password=document.getElementById("password").value; var checkCode=document.getElementById("checkCode").value; axios({ method:"POST", url:"http://localhost:8080${pageContext.request.contextPath}/userAjaxRegister", params:{ username:username, password:password, checkCode:checkCode } }).then(function (result){ var jsonData=result.data; if(jsonData.code!="200"){ alert(jsonData.msg); return; } alert("注册成功"); window.location.href="http://localhost:8080${pageContext.request.contextPath}/login"; }) } </script> <span style="color: red" id="error">${errorMsg}</span><br> <input type="submit" value="注册" οnclick="ajaxRegister()" ><br> <%--</form>--%> </body> </html>
index.jsp
<%-- Created by IntelliJ IDEA. User: 浙李鞠人 Date: 2024/5/10 Time: 23:06 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> 登录的名称为${user.getUsername()} </body> </html>
login.jsp
<%-- Created by IntelliJ IDEA. User: 浙李鞠人 Date: 2024/7/13 Time: 19:18 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %> <html lang="ch"> <head> <meta charset="utf-8"> <title>用户登录</title> </head> <body> <h1>用户登录</h1> <form action="login" method="post"> <label>账 号:</label><input type="text" name="username" value="${cookie.username.value}" ><br> <lable>密 码:</lable><input type="password" name="password" value="${cookie.password.value}"> <label>记住密码</label><input type="checkbox" name="rememberPassword"><br> <input type="submit" value="提交" ><br> <span style="color: red" id="error">${errorMsg}</span> </form> </body> </html>