JavaWeb学习笔记——验证码

验证码

  • 解决的问题
  • kaptcha 的使用
    • 实现
    • 切换验证码

解决的问题

表单重复提交有三种常见的情况:

  1. 表单提交完成之后,服务器使用请求转发进行页面的跳转,此时,若用户按下 F5(刷新),浏览器会重新发起最后一次的请求,造成表单的重复提交。解决方法:使用请求重定向代替请求转发
  2. 用户正常提交表单,但由于网络延迟等原因,迟迟未收到服务器的响应,此时,用户误以为表单提交失败,重复点击提交按钮,造成表单重复提交。解决方法:使用验证码
  3. 用户正常提交表单,服务器也没有延迟,但提交完成后,用户回退浏览器页面(<- 按钮),再重新提交,也会造成表单重复
    提交。解决方法:使用验证码

kaptcha 的使用

实现

kaptcha 是谷歌提供的图片验证码,原理如下:

  1. 客户端访问验证码对应的 Servlet 程序,kaptcha 程序生成验证码,并将正确的验证码保存到 Session 域中,key 为:KAPTCHA_SESSION_KEY
  2. 接收客户端发送的验证码
  3. 取出 Session 域中的验证码,并 立即删除 Session 域中该验证码内容
  4. 比较两个验证码是否相同

每次访问验证码对应的 Servlet 程序后,kaptcha 会将正确验证码的内容保存到 Session 域中,当服务器接收客户端发送的验证码之后,

使用步骤如下:

  1. 导入谷歌 kaptcha 的 jar 包:kaptcha-2.3.2.jar
  2. 在 web.xml 中配置用于生成验证码的 Servlet 程序

JavaWeb学习笔记——验证码_第1张图片
上面的 KaptchaServlet.class 就是谷歌已经写好的用于生成验证码的 Servlet 程序,只需要在 web.xml 中配置该类的访问地址即可。

web.xml

  <!-- 配置谷歌验证码程序KaptchaServlet -->
  <servlet>
  	<servlet-name>KaptchaServlet</servlet-name>
  	<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>KaptchaServlet</servlet-name>
  	<url-pattern>/kaptcha.jpg</url-pattern>
  </servlet-mapping>
  1. 在表单中使用 img 标签显示验证码图片
<form action="http://localhost:8080/tmp/registServlet" method="get">
	用户名:<input type="text" name="username" > <br>
	密码:<input type="password" name="password" > <br>
	验证码:<input type="text" style="width: 80px;" name="code">
	<img id="code_img" src="http://localhost:8080/tmp/kaptcha.jpg" alt="" style="width: 100px; height: 28px;"> <br>
	<input type="submit" value="登录">
</form>
  1. 服务器端验证 Session 域中的验证码与客户端发来的验证码是否相同,并立即删除 Session 域中的验证码
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
     
	// 获取 Session 中的验证码
	String token = (String) req.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
	// 立即删除 Session 中的验证码
	req.getSession().removeAttribute(Constants.KAPTCHA_SESSION_KEY);
	String code = req.getParameter("code");
	// 获取用户名和密码
	String username = req.getParameter("username");
	String password = req.getParameter("password");
	if (token != null && token.equalsIgnoreCase(code)) {
     
		System.out.println("保存到数据库:" + username + ", " + password);
		resp.sendRedirect(req.getContextPath() + "/login_successful.jsp");
	} else {
     
		System.out.println("请不要重复提交表单");
	}
}

切换验证码

//为验证码图片绑定单击事件,使得每次点击验证码图片后都会刷新验证码
$("#code_img").click(function(){
     
	/*
	在事件响应的function函数中有一个this对象,这个this对象,就是当前正在响应事件的dom对象,
	这里表示img标签对象,src属性表示img标签的图片路径,它可读可写
	${ baseAddr }kaptcha.jpg  = http://localhost:8080/tmp/kaptcha.jpg
	浏览器缓存文件的名称由:资源名+参数 组成
	增加一个可变参数d,使得每次请求的名称不同,避免浏览器缓存验证码,导致验证码点击时不刷新的问题
	new Date().getTime()是JavaScript中提供的对象和方法
	*/
	this.src = "${ baseAddr }kaptcha.jpg?" + new Date().getTime();
});

你可能感兴趣的:(笔记,验证码,javaee,web)