会话——验证码注册与记住密码登录

2023-09-23 25 0

文章目录

    • 1、需求分析
    • 2、用户登录功能
      • 2.1、流程分析
      • 2.2、代码实现
      • 2.3、结果演示
    • 3、登录记住密码功能
      • 3.1、流程分析
      • 3.2、代码实现
      • 3.3、结果演示
    • 4、用户注册功能
      • 4.1、流程分析
      • 4.2、代码实现
      • 4.3、结果演示
    • 5、注册验证码功能
      • 5.1、流程分析
      • 5.2、代码实现
      • 5.3、结果演示

1、需求分析

需求说明:

  1. 完成用户登录功能,如果用户勾选“记住用户” ,则下次访问登录页面自动填充用户名密码
  2. 完成注册功能,并实现验证码功能

image-20220211110320583

2、用户登录功能

  • 用户登录成功后,跳转到列表页面,并在页面上展示当前登录的用户名称
  • 用户登录失败后,跳转回登录页面,并在页面上展示对应的错误信息

image-20220211110333638

2.1、流程分析

  1. 前端通过表单发送请求和数据给Web层的LoginServlet
  2. 在LoginServlet中接收请求和数据[用户名和密码]
  3. LoginServlet接收到请求和数据后,调用Service层完成根据用户名和密码查询用户对象
  4. 在Service层需要编写UserService类,在类中实现login方法,方法中调用Dao层的UserMapper
  5. 在UserMapper接口中,声明一个根据用户名和密码查询用户信息的方法
  6. Dao层把数据查询出来以后,将返回数据封装到User对象,将对象交给Service层
  7. Service层将数据返回给Web层
  8. Web层获取到User对象后,判断User对象,如果为Null,则将错误信息响应给登录页面,如果不为Null,则跳转到主界面,并把当前登录用户的信息存入Session携带到主界面中。

image-20220211110813439

2.2、代码实现

登录核心流程

  1. 创建Web项目,这里是不使用骨架进行创建,具体步骤参考往期博客JavaWeb-IDEA利用Tomcat发布网站中的“不使用骨架搭建Web项目

image-20220211111914462

  1. 编写pom.xml文件,导入对应的依赖。其中共需要导入的依赖如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>session-test</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><!-- 防止maven打包时出现乱码 --><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!--servlet--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!--jsp--><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.2</version><scope>provided</scope></dependency><!--jstl--><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version></dependency><!-- 添加slf4j日志api --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.20</version></dependency><!-- 添加logback-classic依赖 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency><!-- 添加logback-core依赖 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.2.3</version></dependency></dependencies><build><plugins><!-- tomcat --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version></plugin></plugins></build></project>
  1. 创建数据库,并新建mybatis-config.xml配置文件

    • 数据库创建
    CREATE DATABASE db1 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;USE db1;CREATE TABLE tb_user (id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(20) UNIQUE,`password` VARCHAR(20)
    );INSERT tb_user(username, `password`)
    VALUES('张三', '123');INSERT tb_user(username, `password`)
    VALUES('李四', '456');SELECT * FROM tb_user;
    
    • xml文件编写
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration><!-- 起别名 --><typeAliases><package name="com.xbaozi.pojo"/></typeAliases><!-- 配置数据库环境 --><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///db1?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf8"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><!--扫描mapper--><mappers><package name="com.xbaozi.mapper"/></mappers>
    </configuration>
    
  2. 创建SQL映射文件

  • 编写接口中的方法
package com.xbaozi.mapper;import com.xbaozi.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;/*** @author xBaozi* @version 1.0* @interfacename UserMapper* @description 创建UserMapper* @date 2022/2/10 14:03*/
public interface UserMapper {/*** @description 根据用户名和密码查询用户对象* @author xBaozi* @date 14:08 2022/2/10* @param username 用户名* @param password 密码* @return 返回一个对应的用户对象,否则为空**/@Select("select * from tb_user where username = #{username} and password = #{password}")User select(@Param("username") String username, @Param("password")  String password);
}
  • 编写mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xbaozi.mapper.UserMapper"></mapper>
  1. 对工具类SqlSessionFactoryUtil进行编写
package com.xbaozi.util;import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;import java.io.IOException;
import java.io.InputStream;/*** @author xBaozi* @version 1.0* @description 对获取SqlSessionFactory对象的语句进行封装* @className SqlSessionFactoryUtil* @date 2022/2/10 16:09*/
public class SqlSessionFactoryUtil {private static SqlSessionFactory sqlSessionFactory = null;static {try {String resource = "mybatis-config.xml";InputStream is = Resources.getResourceAsStream(resource);sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);} catch (IOException e) {e.printStackTrace();}}public static SqlSessionFactory getSqlSessionFactory() {return sqlSessionFactory;}
}
  1. 对Service层中的UserService和LoginService进行编写
  • com.xbaozi.service包下,创建UserService类
package com.xbaozi.service;import com.xbaozi.mapper.UserMapper;
import com.xbaozi.pojo.User;
import com.xbaozi.util.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;/*** @author xBaozi* @version 1.0* @className UserService* @description 封装用户服务类* @date 2022/2/10 16:14*/
public class UserService {/** 获取SqlSessionFactory对象 */SqlSessionFactory factory = SqlSessionFactoryUtil.getSqlSessionFactory();/*** @description 用户登录* @author xBaozi* @date 16:21 2022/2/10* @param username  所登陆的用户名* @param password  对应的登录密码* @return  返回对应的用户对象,否则为空**/public User login(String username, String password) {// 获取SqlSessionSqlSession sqlSession = factory.openSession();// 获取UserMapperUserMapper userMapper = sqlSession.getMapper(UserMapper.class);// 调用方法User user = userMapper.select(username, password);// 释放资源sqlSession.close();return user;}}
  • com.xbaozi.web包下,创建LoginServlet类
package com.xbaozi.web;import com.xbaozi.pojo.User;
import com.xbaozi.service.UserService;import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.nio.charset.StandardCharsets;/*** @author xBaozi* @version 1.0* @className LoginServlet* @description 实现用户登录功能* @date 2022/2/10 16:27*/
@WebServlet(urlPatterns = "/loginServlet")
public class LoginServlet extends HttpServlet {private UserService service = new UserService();@Overrideprotected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {// 1. 获取用户名和密码String username = request.getParameter("username");String password = request.getParameter("password");// 避免用户名存在中文导致乱码username = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);System.out.println("Username: " + username);System.out.println("password: " + password);// 2. 调用UserService的login方法进行查询User user = service.login(username, password);// 3. 对user对象进行判空if (user != null) {//将登陆成功后的user对象,存储到sessionHttpSession session = request.getSession();session.setAttribute("user", user);// 通过request转发request.getRequestDispatcher("/index.jsp").forward(request, response);} else {// 登录失败,存储错误信息到requestrequest.setAttribute("login_msg","用户名或密码错误");// 跳转到login.jsprequest.getRequestDispatcher("/login.jsp").forward(request,response);}}@Overrideprotected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {this.doPost(request, response);}
}
  1. 在webapp下编写前端界面验证后端代码

    • 编写login.jsp,这里值得注意的是表单需要提交到登录对应的Servlet,即loginServlet
    <%--Created by IntelliJ IDEA.User: BaoziDate: 2022/2/10Time: 13:54To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <!DOCTYPE html>
    <html lang="en"><head><meta charset="UTF-8"><title>login</title><link href="css/login.css" rel="stylesheet"></head><body><div id="loginDiv" style="height: 350px"><form action="/session-test/loginServlet" method="post" id="form"><h1 id="loginMsg">LOGIN IN</h1><div id="errorMsg">${login_msg}</div><p>Username:<input id="username" name="username" type="text"></p><p>Password:<input id="password" name="password" type="password"></p><p>Remember:<input id="remember" name="remember" value="1" type="checkbox"></p><div id="subDiv"><input type="submit" class="button" value="login up"><input type="reset" class="button" value="reset">&nbsp;&nbsp;&nbsp;<a href="register.jsp">没有账号?</a></div></form></div></body>
    </html>
    
    • 编写login.css
    * {margin: 0;padding: 0;
    }html {height: 100%;width: 100%;overflow: hidden;margin: 0;padding: 0;background: url(../imgs/Desert1.jpg) no-repeat 0px 0px;background-repeat: no-repeat;background-size: 100% 100%;-moz-background-size: 100% 100%;
    }body {display: flex;align-items: center;justify-content: center;height: 100%;
    }#loginDiv {width: 37%;display: flex;justify-content: center;align-items: center;height: 380px;background-color: rgba(75, 81, 95, 0.3);box-shadow: 7px 7px 17px rgba(52, 56, 66, 0.5);border-radius: 5px;
    }#name_trip {margin-left: 50px;color: red;
    }p {margin-top: 30px;margin-left: 20px;color: azure;
    }#remember{margin-left: 15px;border-radius: 5px;border-style: hidden;background-color: rgba(216, 191, 216, 0.5);outline: none;padding-left: 10px;height: 20px;width: 20px;
    }
    #username{width: 200px;margin-left: 15px;border-radius: 5px;border-style: hidden;height: 30px;background-color: rgba(216, 191, 216, 0.5);outline: none;color: #f0edf3;padding-left: 10px;
    }
    #password{width: 202px;margin-left: 15px;border-radius: 5px;border-style: hidden;height: 30px;background-color: rgba(216, 191, 216, 0.5);outline: none;color: #f0edf3;padding-left: 10px;
    }
    .button {border-color: cornsilk;background-color: rgba(100, 149, 237, .7);color: aliceblue;border-style: hidden;border-radius: 5px;width: 100px;height: 31px;font-size: 16px;
    }#subDiv {text-align: center;margin-top: 30px;
    }
    #loginMsg{text-align: center;color: aliceblue;
    }
    #errorMsg{text-align: center;color:red;
    }
    
    • 编写index.jsp
    <%--Created by IntelliJ IDEA.User: BaoziDate: 2022/2/10Time: 16:42To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html><head><title>index</title></head><body><h1>Welcome! Dear ${user.username}</h1></body>
    </html>

2.3、结果演示

启动Tomcat,打开登录界面进行代码验证

  1. 正确登录情况

image-20220211113329312

image-20220211113454570

  1. 用户名或密码错误情况

image-20220211195614514

image-20220211195757930

3、登录记住密码功能

如果用户勾选“记住用户” ,则下次访问登陆页面自动填充用户名密码。这样可以提升用户的体验。

image-20220212114701169

3.1、流程分析

因为记住我功能要实现的效果是,就算用户把浏览器关闭过几天再来访问也能自动填充,所以需要将登陆信息存入一个可以长久保存,并且能够在浏览器关闭重新启动后依然有效的地方,很容易想到的就是Cookie,所以:

  • 将用户名和密码写入Cookie中,并且持久化存储Cookie,下次访问浏览器会自动携带Cookie
  • 在页面获取Cookie数据后,设置到用户名和密码框中
  • 用户在登陆成功且勾选了记住我的单选框后将用户登录信息写入Cookie
  • 在页面可以使用EL表达式${cookie.key.value}对cookie中数据进行获取,其中的key:指的是存储在cookie中的键名称

image-20220212114829265

3.2、代码实现

  1. login.jsp中的选择框添加值做以判断
<!-- 只单独写出了改变的一条语句 -->
<p>Remember:<input id="remember" name="remember" value="1" type="checkbox"></p>
  1. LoginServlet中的登录成功判断中添加是否勾选了选择框的判断并以此添加cookie
/*** @author xBaozi* @version 1.0* @className LoginServlet* @description 实现用户登录功能* @date 2022/2/10 16:27*/
@WebServlet(urlPatterns = "/loginServlet")
public class LoginServlet extends HttpServlet {private UserService service = new UserService();private String REMEMBER_KEY = "1";@Overrideprotected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {// 1. 获取用户名和密码String username = request.getParameter("username");String password = request.getParameter("password");// 获取单选框中的值String remember = request.getParameter("remember");// 避免用户名存在中文导致乱码username = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);System.out.println("Username: " + username);System.out.println("password: " + password);// 2. 调用UserService的login方法进行查询User user = service.login(username, password);// 3. 对user对象进行判空if (user != null) {// 判断用户是否勾选记住我,字符串写前面是为了避免出现空指针异常if (REMEMBER_KEY.equals(remember)) {// 创建Cookie对象Cookie cUsername = new Cookie("username", URLEncoder.encode(username, "UTF-8"));Cookie cPassword = new Cookie("password", password);// 设置Cookie存活时间为7天cUsername.setMaxAge(60 * 60 * 24 * 7);cPassword.setMaxAge(60 * 60 * 24 * 7);// 添加Cookie对象response.addCookie(cUsername);response.addCookie(cPassword);}//将登陆成功后的user对象,存储到sessionHttpSession session = request.getSession();session.setAttribute("user", user);// 通过request转发request.getRequestDispatcher("/index.jsp").forward(request, response);} else {// 登录失败,存储错误信息到requestrequest.setAttribute("login_msg","用户名或密码错误");// // 通过request转发,跳转到login.jsprequest.getRequestDispatcher("/login.jsp").forward(request,response);}}@Overrideprotected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {this.doPost(request, response);}
}
  1. 再次对login.jsp进行修改从而获取cookie,并通过EL表达式将对应的账号密码分别设置为账号和密码输入框中的值
<%@ page import="java.net.URLDecoder" %><%--Created by IntelliJ IDEA.User: BaoziDate: 2022/2/10Time: 13:54To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%String username = "";Cookie[] cookies = request.getCookies();for (Cookie cookie : cookies) {if ("username".equals(cookie.getName())) {username = URLDecoder.decode(cookie.getValue(), "utf-8");request.setAttribute("username", username);break;}}
%>
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>login</title><link href="css/login.css" rel="stylesheet"></head><body><div id="loginDiv" style="height: 350px"><form action="/session-test/loginServlet" method="post" id="form"><h1 id="loginMsg">LOGIN IN</h1><div id="errorMsg">${login_msg}</div><p>Username:<input id="username" name="username" value="${username}" type="text"></p><p>Password:<input id="password" name="password" value="${cookie.password.value}" type="password"></p><p>Remember:<input id="remember" name="remember" value="1" type="checkbox"></p><div id="subDiv"><input type="submit" class="button" value="login up"><input type="reset" class="button" value="reset">&nbsp;&nbsp;&nbsp;<a href="register.jsp">没有账号?</a></div></form></div></body>
</html>

3.3、结果演示

启动Tomcat,对该功能进行演示。

  1. 没有勾选记住我选项的情况,刷新再次进入登录界面会发现没有保存账号密码

image-20220211113329312

image-20220212120345078

  1. 勾选了记住我选项的情况,刷新再次进入登录界面会发现默认输入了上次登录时的账号密码

image-20220212120729193

4、用户注册功能

  • 注册功能:保存用户信息到数据库

  • 验证码功能

    • 展示验证码:展示验证码图片,并可以点击切换
    • 校验验证码:验证码填写不正确,则注册失败

    image-20220212121913115

4.1、流程分析

  1. 前端通过表单发送请求和数据给Web层的RegisterServlet
  2. 在RegisterServlet中接收请求和数据[用户名和密码]
  3. RegisterServlet接收到请求和数据后,调用Service层完成用户信息的保存
  4. 在Service层需要编写UserService类,在类中实现register方法,需要判断用户是否已经存在,如果不存在,则完成用户数据的保存
  5. 在UserMapper接口中,声明两个方法,一个是根据用户名查询用户信息方法,另一个是保存用户信息方法
  6. 在UserService类中保存成功则返回true,失败则返回false,将数据返回给Web层
  7. Web层获取到结果后,如果返回的是true,则提示注册成功,并转发到登录页面,如果返回false则提示用户名已存在并转发到注册页面

image-20220212122104331

4.2、代码实现

  1. 完成Dao层中的接口编写
package com.xbaozi.mapper;import com.xbaozi.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;/*** @author xBaozi* @version 1.0* @interfacename UserMapper* @description 创建UserMapper* @date 2022/2/10 14:03*/
public interface UserMapper {/*** @description 根据用户名和密码查询用户对象* @author xBaozi* @date 14:08 2022/2/10* @param username 用户名* @param password 密码* @return 返回一个对应的用户对象,否则为空**/@Select("select * from tb_user where username = #{username} and password = #{password}")User select(@Param("username") String username, @Param("password")  String password);/*** @description 根据用户名查询用户对象* @author xBaozi* @date 14:15 2022/2/10* @param username 用户名* @return  返回一个对应的用户对象,否则为空**/@Select("select * from tb_user where username = #{username}")User selectByName(@Param("username") String username);/*** @description 添加用户* @author xBaozi* @date 14:18 2022/2/10* @param user  需要添加的用户对象**/@Insert("insert into tb_user values(null, #{username}, #{password})")void addUser(User user);
}
  1. 编写Service层中UserService的注册方法
/*** @description 用户注册* @author xBaozi* @date 11:35 2022/2/13* @param user  需要注册的用户对象* @return      返回是否注册成功**/
public boolean register(User user) {// 获取SqlSessionSqlSession sqlSession = factory.openSession();// 获取UserMapperUserMapper userMapper = sqlSession.getMapper(UserMapper.class);// 调用方法User u = userMapper.selectByName(user.getUsername());// 对用户是否存在判定if (u == null) {// 用户不存在进行注册操作userMapper.addUser(user);sqlSession.commit();}// 关闭资源sqlSession.close();return u == null;
}
  1. 编写RegisterServlet实现注册功能
/*** @author xBaozi* @version 1.0* @className RegisterServlet* @description 实现用户注册功能* @date 2022/2/15 14:17*/
@WebServlet(urlPatterns = "/registerServlet")
public class RegisterServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1. 获取用户名和密码数据String username = request.getParameter("username");String password = request.getParameter("password");// 避免用户名存在中文导致乱码username = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);// 2. 封装成User对象User user = new User();user.setUsername(username);user.setPassword(password);// 3. 调用service中的注册方法boolean isRegister = new UserService().register(user);// 4. 判断是否注册成功if (isRegister) {// 注册成功request.setAttribute("register_msg", "新用户注册成功");request.getRequestDispatcher("login.jsp").forward(request, response);} else {// 注册失败request.setAttribute("register_msg", "该用户名已存在");request.getRequestDispatcher("register.jsp").forward(request, response);}}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}
}
  1. 完成register.jsp的编写进行测试
<%--Created by IntelliJ IDEA.User: BaoziDate: 2022/2/15Time: 14:39To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>欢迎注册</title><link href="css/register.css" rel="stylesheet"></head><body><div class="form-div"><div class="reg-content"><h1>欢迎注册</h1><span>已有帐号?</span> <a href="login.html">登录</a></div><form id="reg-form" action="/session-test/registerServlet" method="post"><table><tr><td>用户名</td><td class="inputs"><input name="username" type="text" id="username"><br><span id="username_err" class="err_msg">${register_msg}</span></td></tr><tr><td>密码</td><td class="inputs"><input name="password" type="password" id="password"><br><span id="password_err" class="err_msg" style="display: none">密码格式有误</span></td></tr><tr><td>验证码</td><td class="inputs"><input name="checkCode" type="text" id="checkCode"><img src="imgs/a.jpg"><a href="#" id="changeImg" >看不清?</a></td></tr></table><div class="buttons"><input value="注 册" type="submit" id="reg_btn"></div><br class="clear"></form></div></body>
</html>--------------------css---------------------* {margin: 0;padding: 0;list-style-type: none;
}
.reg-content{padding: 30px;margin: 3px;
}
a, img {border: 0;
}body {background-image: url("../imgs/reg_bg_min.jpg") ;text-align: center;
}table {border-collapse: collapse;border-spacing: 0;
}td, th {padding: 0;height: 90px;}
.inputs{vertical-align: top;
}.clear {clear: both;
}.clear:before, .clear:after {content: "";display: table;
}.clear:after {clear: both;
}.form-div {background-color: rgba(255, 255, 255, 0.27);border-radius: 10px;border: 1px solid #aaa;width: 424px;margin-top: 150px;margin-left:1050px;padding: 30px 0 20px 0px;font-size: 16px;box-shadow: inset 0px 0px 10px rgba(255, 255, 255, 0.5), 0px 0px 15px rgba(75, 75, 75, 0.3);text-align: left;
}.form-div input[type="text"], .form-div input[type="password"], .form-div input[type="email"] {width: 268px;margin: 10px;line-height: 20px;font-size: 16px;
}.form-div input[type="checkbox"] {margin: 20px 0 20px 10px;
}.form-div input[type="button"], .form-div input[type="submit"] {margin: 10px 20px 0 0;
}.form-div table {margin: 0 auto;text-align: right;color: rgba(64, 64, 64, 1.00);
}.form-div table img {vertical-align: middle;margin: 0 0 5px 0;
}.footer {color: rgba(64, 64, 64, 1.00);font-size: 12px;margin-top: 30px;
}.form-div .buttons {float: right;
}input[type="text"], input[type="password"], input[type="email"] {border-radius: 8px;box-shadow: inset 0 2px 5px #eee;padding: 10px;border: 1px solid #D4D4D4;color: #333333;margin-top: 5px;
}input[type="text"]:focus, input[type="password"]:focus, input[type="email"]:focus {border: 1px solid #50afeb;outline: none;
}input[type="button"], input[type="submit"] {padding: 7px 15px;background-color: #3c6db0;text-align: center;border-radius: 5px;overflow: hidden;min-width: 80px;border: none;color: #FFF;box-shadow: 1px 1px 1px rgba(75, 75, 75, 0.3);
}input[type="button"]:hover, input[type="submit"]:hover {background-color: #5a88c8;
}input[type="button"]:active, input[type="submit"]:active {background-color: #5a88c8;
}
.err_msg{color: red;padding-right: 170px;
}
#password_err,#tel_err{padding-right: 195px;
}#reg_btn{margin-right:50px; width: 285px; height: 45px; margin-top:20px;
}#checkCode{width: 100px;
}#changeImg{color: aqua;
}
  1. 如果注册成功,需要把成功信息展示在登录页面,所以也需要修改login.jsp
修改前:<div id="errorMsg">${login_msg}</div>
修改后:<div id="errorMsg">${login_msg} ${register_msg}</div>

4.3、结果演示

  1. 用户名已存在情况

image-20220215152136429

  1. 注册成功情况

image-20220215152221877

5、注册验证码功能

展示验证码:展示验证码图片,并可以点击切换。

  • 验证码就是使用Java代码生成的一张图片

  • 验证码的作用:防止机器自动注册,攻击服务器

  • 生成验证码和校验验证码是两次请求,此处就需要在一个会话的两次请求之间共享数据

  • 验证码属于安全数据类的,所以我们选中Session来存储验证码数据。

5.1、流程分析

  1. 前端发送请求给CheckCodeServlet
  2. CheckCodeServlet接收到请求后,生成验证码图片,将图片用Reponse对象的输出流写回到前端
  3. 在CheckCodeServlet中生成验证码的时候,将验证码数据存入Session对象
  4. 前端将验证码和注册数据提交到后台,交给RegisterServlet类
  5. RegisterServlet类接收到请求和数据后,其中就有验证码,和Session中的验证码进行对比
  6. 如果一致,则完成注册,如果不一致,则提示错误信息

image-20220215152912357

5.2、代码实现

  1. 编写CheckCodeServlet类,用来接收请求生成验证码与接收
/*** @author xBaozi* @version 1.0* @className CheckCodeServlet* @description 用于验证码的生成和验证* @date 2022/2/15 15:33*/
@WebServlet(urlPatterns = "/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 生成验证码ServletOutputStream os = response.getOutputStream();String checkCode = CheckCodeUtil.outputVerifyImage(100, 50, os, 4);System.out.println(checkCode);// 将数据存入sessionHttpSession session = request.getSession();session.setAttribute("CheckCodeGen", checkCode);}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}
}
  1. 在RegisterServlet中,获取页面的和session对象中的验证码,进行对比
/*** @author xBaozi* @version 1.0* @className RegisterServlet* @description 实现用户注册功能* @date 2022/2/15 14:17*/
@WebServlet(urlPatterns = "/registerServlet")
public class RegisterServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1. 获取用户名和密码数据String username = request.getParameter("username");String password = request.getParameter("password");// 避免用户名存在中文导致乱码username = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);// 2. 封装成User对象User user = new User();user.setUsername(username);user.setPassword(password);// 获取用户输入的验证码String checkCode = request.getParameter("checkCode");// 程序生成的验证码,从Session获取HttpSession session = request.getSession();String checkCodeGen = (String) session.getAttribute("CheckCodeGen");// 比对if(!checkCodeGen.equalsIgnoreCase(checkCode)){request.setAttribute("register_msg","验证码错误");request.getRequestDispatcher("/register.jsp").forward(request,response);// 不允许注册return;}// 3. 调用service中的注册方法boolean isRegister = new UserService().register(user);// 4. 判断是否注册成功if (isRegister) {// 注册成功request.setAttribute("register_msg", "新用户注册成功");request.getRequestDispatcher("login.jsp").forward(request, response);} else {// 注册失败request.setAttribute("register_msg", "该用户名已存在");request.getRequestDispatcher("register.jsp").forward(request, response);}}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}
}
  1. 修改register.jsp界面代码,并添加点击事件
<%--Created by IntelliJ IDEA.User: BaoziDate: 2022/2/15Time: 14:39To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>欢迎注册</title><link href="css/register.css" rel="stylesheet"></head><body><div class="form-div"><div class="reg-content"><h1>欢迎注册</h1><span>已有帐号?</span> <a href="login.html">登录</a></div><form id="reg-form" action="/session-test/registerServlet" method="post"><table><tr><td>用户名</td><td class="inputs"><input name="username" type="text" id="username"><br><span id="username_err" class="err_msg">${register_msg}</span></td></tr><tr><td>密码</td><td class="inputs"><input name="password" type="password" id="password"><br><span id="password_err" class="err_msg" style="display: none">密码格式有误</span></td></tr><tr><td>验证码</td><td class="inputs"><input name="checkCode" type="text" id="checkCode"><img id="checkCodeImg" src="/session-test/checkCodeServlet"><a href="#" id="changeImg" >看不清?</a></td></tr></table><div class="buttons"><input value="注 册" type="submit" id="reg_btn"></div><br class="clear"></form></div><script><%-- a标签点击事件 --%>document.getElementById("changeImg").onclick = function () {document.getElementById("checkCodeImg").src = "/session-test/checkCodeServlet?"+new Date().getMilliseconds();}<%-- 图片点击事件 --%>document.getElementById("checkCodeImg").onclick = function () {document.getElementById("checkCodeImg").src = "/session-test/checkCodeServlet?"+new Date().getMilliseconds();}</script></body>
</html>

5.3、结果演示

  1. 验证码缺省或错误

image-20220215160118233

  1. 验证码正确且注册用户合法

image-20220215160323771

完结走人

在这里插入图片描述

代码编程
赞赏

相关文章

外贸企业邮箱注册哪个好?怎么申请企业邮箱,两步轻松完成
外贸行业等公司企业邮箱不可替代的重要性
最走心的商务邮箱有哪些,如何拥有一个与众不同的电子邮箱!
初入职场的你知道如何向领导邮件汇报工作吗
邮件误删恢复,一个功能强大的企业邮箱
公司企业邮箱怎么选择?哪家企业邮箱品牌最好用?