在开发JavaWeb应用时,动态生成能够局部刷新的验证码是一项必须的功能,在这里我们将会详细的讲解如何实现这一功能。

一、涉及技术

该功能需要用到AJAX异步传输技术,这样能保证在点击“看不清,重新获取验证码”按钮时,能够不刷新页面其它内容而局部刷新验证码图片内容。

还需要用到Servlet技术,这里会在Servlet的GET方法中通过Java内置的画图工具绘制一个验证码图片,可以在HTML的<img/>标签中的src属性获取缓存图片资源。

二、各个页面及代码

1.index.html,是一个简单的表单,上面仅有简单几项内容,AJAX异步传输技术也在上面体现,代码中有详细注释。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8"/>
  5. <title>验证码测试</title>
  6. </head>
  7. <body>
  8. <script style="javascript">
  9. var xmlHttp;
  10. //异步刷新验证码
  11. function reload() {
  12. //针对不同浏览器,不同的方式生成xmlHttp对象
  13. try{
  14. xmlHttp=new XMLHttpRequest();
  15. }catch(e){
  16. try{
  17. xmlHttp=new ActiveXObject("Msxml2.XMLHttp");
  18. }catch(e){
  19. try{
  20. xmlHttp=new ActiveXObject("Microsoft.XMLHttp");
  21. }catch(e){
  22. alert("你的浏览器不支持AJAX")   ;
  23. return false;
  24. }
  25. }
  26. }
  27. var url="ValidateCodeServlet";
  28. xmlHttp.onreadystatechange = deal;//该属性为一个函数
  29. xmlHttp.open("GET", url, true);//初始化xmlHttp
  30. xmlHttp.send(null);//发送
  31. }
  32. function deal(){
  33. if(xmlHttp.readyState==4){//当状态值为4时,接收到服务器传输的信息
  34. //重新从servlet获得图片资源,并且防止浏览器缓存,加了时间
  35. document.getElementById("validate_code").src = "ValidateCodeServlet?" + new Date().getTime();
  36. }
  37. }
  38. </script>
  39. <form method="post" action="check.jsp">
  40. <input type="text" name="input_code"/>
  41. <img  src="ValidateCodeServlet" id="validate_code"/>
  42. <a href="#" onclick="reload()">看不清楚,换一个</a>
  43. <input type="submit"/>
  44. </form>
  45. </body>
  46. </html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>验证码测试</title> </head>

<body> <script style="javascript">

var xmlHttp;

//异步刷新验证码

function reload() {

//针对不同浏览器,不同的方式生成xmlHttp对象

try{

xmlHttp=new XMLHttpRequest();

}catch(e){

try{

xmlHttp=new ActiveXObject("Msxml2.XMLHttp");

}catch(e){

try{

xmlHttp=new ActiveXObject("Microsoft.XMLHttp");

}catch(e){

alert("你的浏览器不支持AJAX") ;

return false;

}

}

}

var url="ValidateCodeServlet";

xmlHttp.onreadystatechange = deal;//该属性为一个函数

xmlHttp.open("GET", url, true);//初始化xmlHttp

xmlHttp.send(null);//发送

}

function deal(){

if(xmlHttp.readyState==4){//当状态值为4时,接收到服务器传输的信息

//重新从servlet获得图片资源,并且防止浏览器缓存,加了时间

document.getElementById("validate_code").src = "ValidateCodeServlet?" + new Date().getTime();

}

}

</script>

<form method="post" action="check.jsp">

<input type="text" name="input_code"/>

<img src="ValidateCodeServlet" id="validate_code"/>

<a href="#" onclick="reload()">看不清楚,换一个</a>

<input type="submit"/>

</form>

</body>

</html>

2.check.jsp,用来判断用户表单提交的验证码是否正确,也是较为简单的Java代码。

  1. <%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" language="java" %>  
  2. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  
  3. <html>  
  4. <head>  
  5.     <title>检验验证码</title>  
  6. </head>  
  7. <body>  
  8. <%  
  9.     String code = (String) session.getAttribute("code");  
  10.     String input_code = request.getParameter("input_code");  
  11.   
  12.     if (code != null && input_code != null) {  
  13.         input_code = input_code.toUpperCase();  
  14.         if (code.equals(input_code)) {  
  15.             out.print("验证码正确");  
  16.         } else {  
  17.             out.print("验证码错误");  
  18.         }  
  19.     }  
  20. %>  
  21. <a href="index.html">返回填写页面</a>  
  22. </body>  
  23. </html>  
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" language="java" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<html>

<head>

<title>检验验证码</title>

</head>

<body>

<%

String code = (String) session.getAttribute("code");

String input_code = request.getParameter("input_code");
if (code != null &amp;&amp; input_code != null) {
input_code = input_code.toUpperCase();
if (code.equals(input_code)) {
out.print("验证码正确");
} else {
out.print("验证码错误");
}
}

%>

<a href="index.html">返回填写页面</a>

</body>

</html>

3.ValidateCodeServlet,生成验证码图片的文件,代码中有详细的注释。

  1. package com.yykj.servlet;  
  2.   
  3. import javax.imageio.ImageIO;  
  4. import javax.servlet.ServletException;  
  5. import javax.servlet.http.;  
  6. import java.awt.;  
  7. import java.awt.image.BufferedImage;  
  8. import java.io.IOException;  
  9. import java.util.Random;  
  10.   
  11. public class ValidateCodeServlet extends HttpServlet {  
  12.   
  13.     private Random random = new Random();  
  14.     private String[] allCodes = {  
  15.         "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",  
  16.             "A", "B", "C", "D", "E", "F", "G", "H", "I",  
  17.             "J", "K", "L", "M", "N", "O", "P", "Q", "R",  
  18.             "S", "T", "U", "V", "W", "X", "Y", "Z"  
  19.     };  
  20.     @Override  
  21.     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
  22.         resp.setHeader("Pragma", "No-cache");  
  23.         resp.setHeader("Cache-Control", "No-cache");  
  24.         resp.setDateHeader("Expires", 0);//禁止客户端缓存页面  
  25.         resp.setContentType("image/jpg");//设置响应正文类型为图片  
  26.   
  27.         int height = 20;  
  28.         int width = 60;  
  29.         BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
  30.         Graphics g = image.getGraphics();//获取处理图片的画笔  
  31.         g.setColor(getRandomColor(200, 250));//设置背景色  
  32.         g.fillRect(0, 0, width, height);//画一个矩形  
  33.         g.setFont(new Font("Times New Roman", Font.PLAIN, 18));//设置字体  
  34.         g.setColor(getRandomColor(160, 200));//设置干扰线的颜色  
  35.         for (int i = 0; i < 100; i++){//画一百条干扰线  
  36.             int x = random.nextInt(width);  
  37.             int y = random.nextInt(height);  
  38.             int x1 = random.nextInt(10);  
  39.             int y1 = random.nextInt(10);  
  40.             g.drawLine(x, y, x1, y1);//干扰线的两个顶点坐标  
  41.         }  
  42.   
  43.         String strCode = "";  
  44.         for (int i = 0; i < 4; i++){//生成四个随机字符  
  45.             String strNumber = allCodes[random.nextInt(36)];  
  46.             strCode += strNumber;  
  47.             g.setColor(getRandomColor(20, 120));  
  48.             g.drawString(strNumber , 13 * i + 3, 16);  
  49.         }  
  50.         req.getSession(true).setAttribute("code", strCode);//将生成的验证码存入session  
  51.         g.dispose();//释放图像的上下文资源  
  52.         ImageIO.write(image, "JPEG", resp.getOutputStream());//输出JPEG格式图像  
  53.         resp.getOutputStream().flush();//刷新输出流  
  54.         resp.getOutputStream().close();//关闭输出流  
  55.     }  
  56.   
  57.     @Override  
  58.     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
  59.         doGet(req, resp);  
  60.     }  
  61.     //生成随机RGB颜色  
  62.     private Color getRandomColor(int min, int max){  
  63.         int r = min + random.nextInt(max - min);  
  64.         int b = min + random.nextInt(max - min);  
  65.         int g = min + random.nextInt(max - min);  
  66.         return new Color(r, b, g);  
  67.     }  
  68. }  
package com.yykj.servlet;

import javax.imageio.ImageIO;

import javax.servlet.ServletException;

import javax.servlet.http.;

import java.awt.
;

import java.awt.image.BufferedImage;

import java.io.IOException;

import java.util.Random; public class ValidateCodeServlet extends HttpServlet {
private Random random = new Random();
private String[] allCodes = {
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z"
};
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setHeader("Pragma", "No-cache");
resp.setHeader("Cache-Control", "No-cache");
resp.setDateHeader("Expires", 0);//禁止客户端缓存页面
resp.setContentType("image/jpg");//设置响应正文类型为图片 int height = 20;
int width = 60;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();//获取处理图片的画笔
g.setColor(getRandomColor(200, 250));//设置背景色
g.fillRect(0, 0, width, height);//画一个矩形
g.setFont(new Font("Times New Roman", Font.PLAIN, 18));//设置字体
g.setColor(getRandomColor(160, 200));//设置干扰线的颜色
for (int i = 0; i &lt; 100; i++){//画一百条干扰线
int x = random.nextInt(width);
int y = random.nextInt(height);
int x1 = random.nextInt(10);
int y1 = random.nextInt(10);
g.drawLine(x, y, x1, y1);//干扰线的两个顶点坐标
} String strCode = "";
for (int i = 0; i &lt; 4; i++){//生成四个随机字符
String strNumber = allCodes[random.nextInt(36)];
strCode += strNumber;
g.setColor(getRandomColor(20, 120));
g.drawString(strNumber , 13 * i + 3, 16);
}
req.getSession(true).setAttribute("code", strCode);//将生成的验证码存入session
g.dispose();//释放图像的上下文资源
ImageIO.write(image, "JPEG", resp.getOutputStream());//输出JPEG格式图像
resp.getOutputStream().flush();//刷新输出流
resp.getOutputStream().close();//关闭输出流
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
//生成随机RGB颜色
private Color getRandomColor(int min, int max){
int r = min + random.nextInt(max - min);
int b = min + random.nextInt(max - min);
int g = min + random.nextInt(max - min);
return new Color(r, b, g);
}

}

注意:ValidateCodeServlet要在web.xml中配置,配置代码如下:

  1. <servlet>
  2. <servlet-name>ValidateCodeServlet</servlet-name>
  3. <servlet-class>com.yykj.servlet.ValidateCodeServlet</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6. <servlet-name>ValidateCodeServlet</servlet-name>
  7. <url-pattern>/ValidateCodeServlet</url-pattern>
  8. </servlet-mapping>
  <servlet>
<servlet-name>ValidateCodeServlet</servlet-name>
<servlet-class>com.yykj.servlet.ValidateCodeServlet</servlet-class>
</servlet> <servlet-mapping>

<servlet-name>ValidateCodeServlet</servlet-name>

<url-pattern>/ValidateCodeServlet</url-pattern>

</servlet-mapping>

动态生成能够局部刷新的验证码【AJAX技术】---看了不懂赔你钱的更多相关文章

  1. (局部刷新)jquery.ajax提交并实现单个div刷新

    web开发中我们经常会遇到局部刷新页面的需求,以前我经常使用ajax和iframe实现局部刷新,后来做政府的项目,对页面的样式要求比较多,发现使用iframe控制样式什么的很麻烦,所以就采用了新的办法 ...

  2. Jquery mobile动态生成ListView调用刷新方法报错

    错误:cannot call methods on listview prior to initialization... 示例: <div data-role="page" ...

  3. 动态生成navmeshi-进击的新版NavMesh系统:看我飞檐走壁

    http://forum.china.unity3d.com/thread-25421-1-1.html0x00 前言 unity5.6作为Unity5最后的一个版本,的确起到了一个承上启下的作用.除 ...

  4. ajax局部刷新

    //5秒刷新一次 $(function () { setInterval(Refresh, 5000); }); //ajax局部刷新 function Refresh() { $.ajax({ ty ...

  5. 模拟Hibernate动态生成SQL语句

    这里有一个xml配置文件,也就是Hibernate框架中会用到的POJO和数据库的映射文件 <?xml version="1.0" encoding="utf-8& ...

  6. 用户登录ajax局部刷新验证码

    用户登录的时候,登录页面附带验证码图片,用户需要输入正确的验证码才可以登录,验证码实现局部刷新操作. 效果如图: 代码如下: #生成验证码及图片的函数  newcode.py import rando ...

  7. jquery ajax thinkphp异步局部刷新完整流程

    环境:ThinkPHP3.2.3,jQuery3.2   前言: 在一般的网站中,都需要用到jquery或者其他框架(比如angular)来处理前后端数据交互,thinkphp在后台也内置了一些函数用 ...

  8. Ajax 局部刷新 异步提交

    AJAX简介 局部刷新,异步提交. AJAX 不是新的编程语言,而是一种使用现有标准的新方法.它最大的有点就是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容. 浏览器朝后端发送请 ...

  9. ajax+php+mysql 实现点赞、局部刷新,每个IP只能对一篇文章点赞一次

    主要流程: 点赞—>判断当前设备IP是否对当前文章有过点赞记录—>若有记录,弹出提示“已经赞过了”; 若无记录,当前文章点赞数+1,并在记录设备IP点赞记录的表中插入信息. 文章表 art ...

随机推荐

  1. css 背景图居中

    参考:http://www.php.cn/css-tutorial-411901.html position : 50% ;或position : center;

  2. 07.Hibernate常用的接口和类---Session接口☆☆☆☆☆

    一.特点 Session是在Hibernate中使用最频繁的接口.也被称之为持久化管理器.它提供了和持久化有关的操作,比如添加.修改.删除.加载和查询实体对象 Session 是应用程序与数据库之间交 ...

  3. springboot+atomikos+多数据源管理事务(mysql 8.0)

    jta:Java Transaction API,即是java中对事务处理的api 即 api即是接口的意思 atomikos:Atomikos TransactionsEssentials 是一个为 ...

  4. css3的2D变形

    一.2D变形 1.变形 transform:translate();translateX();translateY();translate(,); 2.过渡 transition:all 1s; 二. ...

  5. QEventLoop配合QTimer实现阻塞任务超时处理

    A阻塞主线程正常运行,需要做特殊处理. 以下代码可实现,A阻塞或者正常处理时,均不阻塞主线程正常处理. QEventLoop eventloop; // use point to manage eve ...

  6. pycharm新手入门

    1.新建项目 2.配置 3.create 4.新建.py文件 5.可以愉快的敲代码啦

  7. 数据库访问技术 odbc dao rdo uda jet oledb

    一.UDA(UniversalDataAccess) 这是微软提供的通用数据访问策略.包括ADO.OLEDB和ODBC.它不光提供了数据库的访 问能力,对于其它的数据存储技术也同样支持,如目录服务.E ...

  8. SVN添加自动忽略文件.settings .project .classpath target等

    eclipse svn提交忽略文件及文件夹,ignore设置无效.. 一.方法: 1. 将文件夹或文件从Eclipse中删除.记得要在Eclipse中删除,而不是Windows文件管理界面删除. 2. ...

  9. 关于node中 require 和 ES6中export 、export default的总结

    nodejs中 require 方法的加载规则 方法的加载规则 1. 优先从缓存中加载 2. 核心模块 3. 路径形式的模块 4. 第三方模块 一.优先从缓存中加载 main.js:执行加载a.js模 ...

  10. html文档加载顺序简单理解

    html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...