从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • RSS
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金等
  • 职场规划
  • 关于离职
  • 杂谈
  • 📖 读书

    • 读书工具
    • 读书笔记
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • RSS
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金等
  • 职场规划
  • 关于离职
  • 杂谈
  • 📖 读书

    • 读书工具
    • 读书笔记
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

  • JavaSenior

  • JavaEE

  • JavaWeb

    • 服务器软件

    • 环境管理和配置管理-科普篇
    • Servlet入门

      • 什么是 Servlet
      • Servlet 入门案例
      • Servlet 生命周期
      • Servlet 中的注解
      • Tomcat 集成 IDEA
      • Servlet 体系结构
      • HTTP 协议基础
      • 深入 request 和 response 对象
      • request 对象基本使用
      • request 其他功能
      • Servlet 实现登录功能
      • HTTP 协议基础-响应
      • Response 对象基本使用
      • response 对象之重定向
      • response 输出字符到浏览器
      • response 输出字节数据
      • 验证码案例
      • ServletContext
      • 文件下载案例
      • Cookie 笔记
      • Cookie 的更多细节
      • Cookie 实践:记住上次访问时间
      • JSP 入门
      • JSP 的内置对象和案例
      • IDEA 与 JavaWeb 的小技巧
      • Session 笔记
      • 验证码案例
        • 需求
        • 准备包
        • 登录页面login.jsp
        • checkCodeServlet
        • LoginServlet
        • success.jsp
        • 修改login.jsp
        • 测试
      • JSP 深入学习
      • MVC 开发模式
      • EL 表达式和 JSTL 标签
      • JSTL 标签库
      • 案例:列表的增删改查
      • Filter 学习
      • Filter 案例
      • Listener 学习
      • Java 中的 Ajax
      • Java 中的 JSON
  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java
  • JavaWeb
  • Servlet入门
2023-04-17
目录

验证码案例

# 105.验证码案例

之前我们的验证码案例,仅仅是生成了一个验证码图片,并没有让用户提交并判断验证码是否正确,今天我们就来完善下这个案例

# 需求

  • 访问带有验证码的登录页面login.jsp

  • 用户输入用户名,密码以及验证码。

    • 如果用户名和密码输入有误,跳转登录页面,提示:用户名或密码错误
    • 如果验证码输入有误,跳转登录页面,提示:验证码错误
    • 如果全部输入正确,则跳转到主页success.jsp,显示:用户名,欢迎您

其实就是在我们的登录案例中加了一个验证码判断(参考Servlet实现登录功能) ‍ 分析如下:

  1. 首先有个登录页面,上面有用户名、密码、验证码输入框、验证码图片和登录按钮;

  2. 用户点击提交后,发送给LoginServlet,开始做如下判断:

    1. 设置req的编码
    2. 获取参数Map集合
    3. 获取验证码,并判断程序生成的验证码(生成后存到Session里)和用户输入的是否一致,不一致则返回
    4. 验证码正确,则将用户信息封装到User对象,然后调用Dao层的方法判断用户名和密码是否正确
    5. 是则存储用户信息,重定向跳转到成功页面,
    6. 不是则给出错误信息(可以在登录页面用JSP来展示信息)

‍

# 准备包

我们新建一个login2的包,并将之前的类复制到这个login2包下:

  1. checkCodeServlet.java
  2. LoginServlet.java

并在所有访问路径后面都加个2,防止冲突,例如/checkCodeServlet2 ‍

# 登录页面login.jsp








 



































<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>login</title>
        <script>
            window.onload = function (){
                var img = document.getElementById("checkCode");
                img.onclick = function (){
                    img.src = "/hello/checkCodeServlet2?date" + new Date().getTime();
                }
            }
        </script>
    </head>
    <body>
        <form action="/hello/loginServlet2">
            <table>
                <tr>
                    <td>用户名</td>
                    <td><input type="text" name="username"></td>
                </tr>

                <tr>
                    <td>密码</td>
                    <td><input type="password" name="password"></td>
                </tr>
                <tr>
                    <td>验证码</td>
                    <td><input type="text" name="checkCode"></td>
                </tr>

                <tr>
                    <td colspan="2"><img id="checkCode" src="/hello/checkCodeServlet2"></td>
                </tr>

                <tr>
                    <td colspan="2"><input type="submit" value="登录"></td>
                </tr>
            </table>
        </form>

    </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

‍ 我们启动下Tomcat,可以看到JSP页面是正常的,并且点击验证码也能切换

# checkCodeServlet

我们需要将生成的验证码存储到Session里,为此我们修改下checkCodeServlet:

StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 4; i++) {
    int index = ran.nextInt(str.length());
    char ch = str.charAt(index);//获取随机字符
    sb.append(ch);
    //2.3写验证码
    g.drawString(ch + "", width/5*i, height/2);
}
req.getSession().setAttribute("checkCode_session", sb.toString());
1
2
3
4
5
6
7
8
9

添加了第1、4和9行

# LoginServlet

package com.peterjxl.login2;

import com.peterjxl.dao.UserDao;
import com.peterjxl.domain.User;
import org.apache.commons.beanutils.BeanUtils;

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.lang.reflect.InvocationTargetException;
import java.util.Map;

@WebServlet("/loginServlet2")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.设置编码
        req.setCharacterEncoding("utf-8");
        //2.获取请求参数
        String name = req.getParameter("username");
        String password = req.getParameter("password");
        String checkCode = req.getParameter("checkCode");

        // 判断验证码是否正确
        HttpSession session = req.getSession();
        String checkCodeSession = (String) session.getAttribute("checkCode_session");
        if(checkCodeSession.equalsIgnoreCase(checkCode)){   //忽略大小写来比较字符串
            //3.封装user对象
            User loginUser = new User();
            loginUser.setName(name);
            loginUser.setPassword(password);

            //4.调用UserDao的login方法
            UserDao dao = new UserDao();
            User user = dao.login(loginUser);

            //5.判断user
            if(user == null){
                //登录失败
                req.setAttribute("error_msg", "用户名或密码错误");
                req.getRequestDispatcher("/login.jsp").forward(req,resp);
            }else{
                //登录成功
                //存储数据
                session.setAttribute("user",user);
                resp.sendRedirect(req.getContextPath() + "/success.jsp");
            }
        }else{  // 验证码不一致
            req.setAttribute("error_msg", "验证码错误");
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

# success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>登录后页面</title>
    </head>
    <body>
      <h1><%= request.getSession().getAttribute("user")%>,欢迎您</h1>
    </body>
</html>
1
2
3
4
5
6
7
8
9

‍

# 修改login.jsp

我们在form表单下面添加一个div,显示错误信息的:

<div> <%= request.getAttribute("error_msg")%></div>
1

# 测试

我们重启Tomcat,访问http://localhost:8080/hello/login.jsp

测试如下情况

  1. 验证码错误
  2. 验证码则正确,但用户密码错误
  3. 验证码正确,用户名密码正确,登录成功 ‍

小优化: ‍ 优化1:在首次打开登录页面时,由于没有错误信息,<div> <%= request.getAttribute("error_msg")%></div>会显示null;我们可以做个优化:

 <div> <%= request.getAttribute("error_msg") == null ? "" : request.getAttribute("error_msg")%></div>

1
2

优化2:我们登录成功后,如果点击浏览器的后退,图片验证码没有被刷新的;再次尝试登录,不用刷新验证码也可以输入密码后登录;我们要确保图形验证码一次一用,在LoginServlet里修改代码

// 判断验证码是否正确
HttpSession session = req.getSession();
String checkCodeSession = (String) session.getAttribute("checkCode_session");
session.removeAttribute("checkCode_session");
1
2
3
4

‍ 由于我们去除了这个属性,当用户点击返回后,再次登录,Servlet获取到的验证码是null,因此我们得加上一个判断

 if( checkCodeSession != null && checkCodeSession.equalsIgnoreCase(checkCode)){   
1
上次更新: 2025/5/5 17:15:09
Session 笔记
JSP 深入学习

← Session 笔记 JSP 深入学习→

最近更新
01
2025 年 4 月记
04-30
02
山西大同 “订婚强奸案” 将会给整个社会带来的影响有多严重? - 知乎 转载
04-26
03
一个小技巧,让电子书阅读体验翻倍!
04-18
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式