在网上找到一份servlet产生验证码的代码,经过测试,发现在页面通过session.getAttribute()方法得到的验证码总是上一次保存在session中的,这样,它总比页面实际的验证码晚一拍。网上一种说法是session早于页面加载。多数人解决方法是用一个中间页面,或者一个servlet来比较输入的验证码是否是session中保存的验证码来解决的,也有通过ajax异步加载来解决的,本人通过中间servlet比较来解决的,测试过程如下,以备后用:



1. 页面

  1. <%@page import="java.util.Date"%>
  2. <%@ page language="java" contentType="text/html; charset=UTF-8"
  3. pageEncoding="UTF-8"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>Insert title here</title>
  9. <%
  10. String context = request.getContextPath();
  11. %>
  12. <script type="text/javascript">
  13. function reloadIdentifyCode() {
  14. document.getElementById("btn").disable = true;
  15. document.getElementById("code").src = "<%=context %>/generateidentifycode?time=" + new Date().getTime();
  16. }
  17. function isIdentifyCodeRight() {
  18. //must quote the jsp sentence
  19. var input = document.getElementById("identify_code").value;
  20. <%
  21. String identifyCode = (String) session.getAttribute("identifyCode");
  22. %>
  23. alert("You input:" + input + ", the answer is:" + "<%=identifyCode %>");
  24. if(input == "<%=identifyCode %>") {
  25. return true;
  26. }
  27. else {
  28. return false;
  29. }
  30. }
  31. </script>
  32. </head>
  33. <body>
  34. <div id="" align="center">
  35. <form action="<%=context %>/user/findpwd" method="post">
  36. <table>
  37. <tr>
  38. <td>用户名:</td>
  39. <td><input id="userName" type="text" value="Email/手机号/用户名" name="userName"></td>
  40. </tr>
  41. <tr>
  42. <td>验证码:</td>
  43. <td><input id="identify_code" type="text" maxlength="6" value="" name="identifyCode">
  44. <img id="code" alt="" src="<%=context %>/generateidentifycode?time=<%=new Date().getTime() %>">
  45. <input id="btn" type="button" value="换张图片" onclick="reloadIdentifyCode()"></td>
  46. </tr>
  47. <tr>
  48. <td colspan="2"><input type="submit" value="发送验证码到邮箱"></td>
  49. </tr>
  50. </table>
  51. </form>
  52. </div>
  53. </body>
  54. </html>
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%
String context = request.getContextPath();
%>
<script type="text/javascript">
function reloadIdentifyCode() {
document.getElementById("btn").disable = true;
document.getElementById("code").src = "<%=context %>/generateidentifycode?time=" + new Date().getTime();
}
function isIdentifyCodeRight() {
//must quote the jsp sentence
var input = document.getElementById("identify_code").value;
<%
String identifyCode = (String) session.getAttribute("identifyCode");
%>
alert("You input:" + input + ", the answer is:" + "<%=identifyCode %>");
if(input == "<%=identifyCode %>") {
return true;
}
else {
return false;
}
}
</script>
</head>
<body>
<div id="" align="center">
<form action="<%=context %>/user/findpwd" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input id="userName" type="text" value="Email/手机号/用户名" name="userName"></td>
</tr>
<tr>
<td>验证码:</td>
<td><input id="identify_code" type="text" maxlength="6" value="" name="identifyCode">
<img id="code" alt="" src="<%=context %>/generateidentifycode?time=<%=new Date().getTime() %>">
<input id="btn" type="button" value="换张图片" onclick="reloadIdentifyCode()"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="发送验证码到邮箱"></td>
</tr>
</table>
</form>
</div>
</body>
</html>

2. 中间servlet

  1. package com.jesse.onlineshop.servlet;
  2. import java.io.IOException;
  3. import java.util.Date;
  4. import java.util.regex.Matcher;
  5. import java.util.regex.Pattern;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.http.HttpServlet;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10. import com.jesse.onlineshop.bean.User;
  11. import com.jesse.onlineshop.exception.DaoException;
  12. import com.jesse.onlineshop.service.UserService;
  13. import com.jesse.onlineshop.service.impl.UserServiceImpl;
  14. /**
  15. * 因为session先于验证码图片加载,在jsp页面通过session得到的验证码总是上一次的,
  16. * 所以,这里借助Ajax通过异步机制来比较用户输入的验证码和session中保存的验证码是 否一致来达到验证的目的
  17. * @author Administrator
  18. *
  19. */
  20. public class FindPassWordServlet extends HttpServlet {
  21. private static final long serialVersionUID = 7331068570820532059L;
  22. private User user;
  23. private UserService userService = new UserServiceImpl();
  24. @Override
  25. protected void doPost(HttpServletRequest req, HttpServletResponse resp)
  26. throws ServletException, IOException {
  27. String input = req.getParameter("identifyCode");    //获取用户输入的code
  28. String answer = (String) req.getSession(false).getAttribute(    //获取session中保存的code
  29. "identifyCode");
  30. if (!input.equalsIgnoreCase(answer)) {
  31. req.getRequestDispatcher("/user/wrongcode.jsp").forward(req, resp);
  32. } else {
  33. String userName = req.getParameter("userName");
  34. String regex = "[0-9]{11}";
  35. Pattern pattern = Pattern.compile(regex);
  36. Matcher matcher = pattern.matcher(userName);
  37. if (matcher.matches()) {
  38. } else if (userName.contains("@")) {
  39. try {
  40. user = userService.getUserByEmail(userName);
  41. } catch (DaoException e) {
  42. e.printStackTrace();
  43. }
  44. } else {
  45. try {
  46. user = userService.getUserByName(userName);
  47. } catch (DaoException e) {
  48. e.printStackTrace();
  49. }
  50. }
  51. String email = user.getEmail();
  52. userName = user.getUserName();
  53. String url = req.getContextPath() + "/confidential/user/changepwd?user="+userName+"&&time=" + new Date().getTime();
  54. try {
  55. userService.addChangePwdReqRecord(userName);
  56. } catch (DaoException e) {
  57. e.printStackTrace();
  58. throw new ServletException(e.getMessage());
  59. }
  60. userService.sendChangePassWordRequest(email, url);
  61. req.getRequestDispatcher("findpwdsuccess.jsp").forward(req, resp);
  62. }
  63. }
  64. }
package com.jesse.onlineshop.servlet;

import java.io.IOException;

import java.util.Date;

import java.util.regex.Matcher;

import java.util.regex.Pattern; import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse; import com.jesse.onlineshop.bean.User;

import com.jesse.onlineshop.exception.DaoException;

import com.jesse.onlineshop.service.UserService;

import com.jesse.onlineshop.service.impl.UserServiceImpl; /**
  • 因为session先于验证码图片加载,在jsp页面通过session得到的验证码总是上一次的,
  • 所以,这里借助Ajax通过异步机制来比较用户输入的验证码和session中保存的验证码是 否一致来达到验证的目的
  • @author Administrator
*/

public class FindPassWordServlet extends HttpServlet {
private static final long serialVersionUID = 7331068570820532059L;

private User user;
private UserService userService = new UserServiceImpl(); @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String input = req.getParameter("identifyCode"); //获取用户输入的code
String answer = (String) req.getSession(false).getAttribute( //获取session中保存的code
"identifyCode");
if (!input.equalsIgnoreCase(answer)) {
req.getRequestDispatcher("/user/wrongcode.jsp").forward(req, resp);
} else {
String userName = req.getParameter("userName");
String regex = "[0-9]{11}";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(userName);
if (matcher.matches()) {
} else if (userName.contains("@")) {
try {
user = userService.getUserByEmail(userName);
} catch (DaoException e) {
e.printStackTrace();
}
} else {
try {
user = userService.getUserByName(userName);
} catch (DaoException e) {
e.printStackTrace();
}
}
String email = user.getEmail();
userName = user.getUserName();
String url = req.getContextPath() + "/confidential/user/changepwd?user="+userName+"&amp;&amp;time=" + new Date().getTime(); try {
userService.addChangePwdReqRecord(userName);
} catch (DaoException e) {
e.printStackTrace();
throw new ServletException(e.getMessage());
} userService.sendChangePassWordRequest(email, url);
req.getRequestDispatcher("findpwdsuccess.jsp").forward(req, resp);
}
}

}

关于在页面得到的servlet验证码总是上一次保存在session中的的更多相关文章

  1. //可以不保存在session中, 并且前面我保存在request,这里session也可以获取 chain.doFilter(request, response); //只有登录名不为空时放行,防止直接登录 成功的页面

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOE ...

  2. ASP.NET上传文件,已经上传的大小保存在session中,在另一个页面中读取session的值不行

    想自己做个ASP.NET上传文件时显示进度条的, 按照自己的想法,其实也就是显示每次已经上传的字节,从网上找到一个方法是能够把文件变成流以后再慢慢写入的,我在那个循环写入的时候每循环一次都把已经上传的 ...

  3. Jsp+servlet 验证码案例

    昨晚在csdn看到一位前辈写一个ajax+servlet+jsp验证.顿时心血来潮,在阅读前辈的代码下我亲手体验一下,做了一个验证码生成工具类.以供大家做个參考. 1:加入VeriyCodeUtils ...

  4. Struts2自定义结果视图(servlet验证码)

    1.编写一个类实现com.opensymphony.xwork2.Result,或者继承org.apache.struts2.dispatcher.StrutsResultSupport 2.自定义的 ...

  5. Tp验证码:$Verify = new \Think\Verify(); $Verify->entry(n);【参数n,页面有多个验证码时用】

    一.验证码参数:(中文字符集和英文字符集在父类里面都可以取到,可修改) //1.生成验证码 $Verify = new \Think\Verify(); $Verify->entry(n);[参 ...

  6. jsp页面转发到servlet

    一个简单的例子来了解一下jsp页面转发到servlet的过程,环境 eclipse.tomcat 1.工程目录结构如下 2.各部分代码如下 1>index.jsp <%@ page lan ...

  7. 使用session和cookie实现用户登录:一个登录页面,一个servlet,一个登录成功页面

    文件目录 1.登录页面 <%@ page language="java" contentType="text/html; charset=utf-8" p ...

  8. 关于使用struts2时子窗体页面跳转后在父窗体打开的问题以及Session过期后的页面跳转问题

    问题1:传统的系统界面,iframe了三个页面,上,左,右,用户点击注销的按钮在上面得top.jsp里面,方法:<a href="../adminAction/admin_logout ...

  9. Servlet实现文件上传,可多文件上传

    一.Servlet实现文件上传,需要添加第三方提供的jar包 接着把这两个jar包放到 lib文件夹下: 二: 文件上传的表单提交方式必须是POST方式, 编码类型:enctype="mul ...

随机推荐

  1. day09 samba、nginx服务配置

    samba 1.环境准备 [root@localhost ~]# iptables -F #清除防火墙配置 [root@localhost ~]# systemctl stop firewalld # ...

  2. Python-进程(1)

    目录 操作系统发展史 穿孔卡片 联机批处理系统 统计批处理系统 单道 多道技术 空间上复用 时间上复用 并行与并发 进程 程序与进程 进程调度 进程的三个状态 就绪态 运行态 阻塞态 同步和异步 阻塞 ...

  3. 上海第三产业增加值 占比GDP首破七成

    上海第三产业增加值 占比GDP首破七成 2016年08月16日08:10  来源:新闻晨报 分享到:     不久前结束的ChinaJoy上,一家名为HYPEREAL的VR公司展台前,体验者的热情程度 ...

  4. 关于前端调用后端php数据跨域的问题

    https://blog.csdn.net/qq_21386275/article/details/87269979 js前端 <!DOCTYPE html><html>< ...

  5. 如何应用AxureRP做原型设计

    什么是原型呢?这个在之前介绍为什么需要进行原型设计当中有提到,原型是产品的最初形态,确认用户对产品界面和操作功能可用性的需求,高保真的原型接近于产品的最终形态,但仍只是原型.产品原型简单的说就是产品设 ...

  6. Python学习day09 - Python进阶(3)

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  7. 第一周课堂笔记2th

    上课笔记2th https://mubu.com/doc/2gxvIvVLG0(老师笔记网址) 1.     python python运行过程 把源代码转化成字节码(机器不能识别) 也可能不产生py ...

  8. 在ALV点击Key值调用TCode,跳过初始屏幕

    在开发ALV报表时,通常业务部门会要求在ALV中点击单据号,屏幕跳转到具体业务凭证中查看业务明细,效果如下图: 点击销售销售订单号或者交货单号可传入单据号直接打开销售订单或交货单,实现方式如下: 一. ...

  9. 将ERF格式转换成PCAP格式

    在研究网络流量分析的时候,wireshark默认采用pcap格式.对于用Endace DAG捕捉卡捕获的数据包,一般来说,都是erf格式的.一般来说,此种格式包含了更多了链路层信息.而我们采用wire ...

  10. #iOS问题记录# 频繁触发viewDidLayoutSubviews的问题

    问题描述: 最近使用给Flutter团队写view组件的时候,出现了触发Widget的频繁build的问题. 问题排查: Flutter的同事提到在flutter层,是因为 updateViewpor ...