Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 2527|回复: 0

Java通用验证码程序及应用示例源码下载

[复制链接]

该用户从未签到

发表于 2011-9-16 11:00:59 | 显示全部楼层 |阅读模式
把之前项目中写的一个java通用验证码程序整理了一下,与大家分享,希望能抛砖引玉。


一、主要功能:
1、支持纯数字、大写字母、小写字母,及两两混合或三者混合类型验证码;
2、支持自定义特殊字符排除(如0oOi1jI);
3、支持图片及文字两种类型验证码;
4、支持自定义验证码图片大小;
5、支持自定义干扰线条数;
6、支持自定义及随机定义图片、文字、干扰线颜色;
其他:示例页面提供了<iframe>和<img>两种页面显示验证码的方式。
a、仅阿拉伯数字

b、仅字母(大小写混合)

c、仅小写字母

d、仅大写字母



d、数字与小写字母混合


e、数字与大写字母混合

f、数字与大小写字母混合

g、自定义字符颜色(或随机)

h、自定义图片颜色(或随机)

i、自定义干扰线的条数及颜色(或随机)

j、自定义验证码图片大小

k、自定义需排除的特殊字符(如0o等难分辨字符)


二、代码说明:
1、pubMsg.jsp 发表留言页面,实现<iframe>和<img>两种显示验证码方式,及ajax提交功能


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
<%
@ page language
=
"
java
"
import
=
"
java.util.*
"
pageEncoding
=
"
gbk
"
%>
<%
String
path
=
request.getContextPath();
String
basePath
=
request.getScheme()
+
"
://
"
+
request.getServerName()
+
"
:
"
+
request.getServerPort()
+
path
+
"
/
"
;
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>
<%
=
basePath
%>
</title>
  </head>
  <script type="text/javascript">
var
req;
//
提交留言
function
pubMsg(){
      msgTitle
=
document.msgForm.msgTitle.value;
      msgContent
=
document.msgForm.msgContent.value;
      verifyCode
=
document.msgForm.verifyCode.value;
//
检查输入内容格式
if
(msgTitle.length
<
5
msgContent.length
<
5
)
      {
          alert(
"
标题和内容不能少于5个字符
"
);
return
;
      }
if
(verifyCode.length
==
0
){
        alert(
"
请输入验证码
"
);
return
;
    }
//
获得XMLHttpRequest对象
if
(window.XMLHttpRequest)
        req
=
new
XMLHttpRequest();
else
if
(window.ActiveXObject)
        req
=
new
ActiveXObject(
"
Microsoft.XMLHTTP
"
);
//
提交请求
if
(req){
        req.onreadystatechange
=
callBack;
//
指定服务器响应结果处理函数(注意仅函数名无括号)
url
=
"
<%=path%>/Servlet/PubMsgServlet?msgTitle=
"
+
msgTitle
+
"
&msgContent=
"
+
msgContent
+
"
&verifyCode=
"
+
verifyCode;
        req.open(
"
GET
"
,url,
false
);
        req.send();
        
    }
  
  }
//
服务器响应结果处理函数
function
callBack(){
if
(req.readyState
==
4
){
if
(req.status
==
200
){
              next
=
req.responseText;
//
获得服务器处理结果
if
(next
==
"
this
"
){
                  alert(
"
验证码不正确,请重新输入
"
);
                  verifyCodeFrame.location.reload();
//
刷新验证码
}
else
{
                  document.msgForm.msgTitle.value
=
""
;
                  document.msgForm.msgContent.value
=
""
;
                  window.location
=
next;
//
跳转页面
}
          }
else
{
              alert(req.status
+
"
:
"
+
req.statusText);
          }
      }
      document.msgForm.verifyCode.value
=
""
;
  }
//
更换验证码
function
changeVerifyCode(){
//
1、如果用<iframe>实现,则重新加载<iframe>的内容
//
verifyCodeFrame.location.reload();
//
2、如果用<img>实现,则修改<img src=url>的url
//
这里有一个小技巧,如果给url赋相同的值,浏览器不会重新发出请求,因此用js生成一个即时毫秒数做url中的参数
t
=
new
Date().getTime();
      document.msgForm.verifyCodeImg.src
=
"
<%=path%>/servlet/VerifyCodeServlet?t=
"
+
t;
  }
</script>
  
  <body>
  
  <form name="msgForm" action="" method="post">
  <table border=0>
  <tr><td>标题:</td><td><input name="msgTitle" size="65"/></td></tr>
  <tr><td>内容:</td><td><textarea name="msgContent" rows="10" cols="64"></textarea></td></tr>
  <tr><td>验证码:</td><td><input name="verifyCode" style="height:29px;width=70px;font-size:25px"/>
  
  <!-- 以下:两种显示验证码的方式 -->
  
  <!-- 1、采用<iframe>实现 -->
  <!--
  <iframe name="verifyCodeFrame" src="<%=path+"/servlet/VerifyCodeServlet"%>"
width="100" height="30" frameborder=0 align="top" marginheight=0 marginwidth=0 scrolling=no></iframe>
   -->
  <!-- 2、采用<img>实现 -->
  <img name="verifyCodeImg" src="<%=path%>/servlet/VerifyCodeServlet"
style="cursor:hand" align="top" onClick="changeVerifyCode()"/>
  
  <!-- 以上:两种显示验证码的方式 -->
  
  
  <font style="color:blue;font-size=14"><a href="javascript:changeVerifyCode()">看不清?</a>
</font>        
  <input type="button" value=" 发表留言 " onClick="pubMsg()"/></td></tr>
  </table>
  </form>
  
  </body>
  
</html>

2、ok.jsp 留言发布成功页面(示意)



Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->
<%
@ page language
=
"
java
"
import
=
"
java.util.*
"
pageEncoding
=
"
gbk
"
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>
    您的留言已提交!<input type="button" value=" OK " onClick="window.history.go(-1)"/><br>
  </body>
</html>


3、org.javachina.util.VerifyCode.java 验证码生成器类
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->package org.javachina.util;
import java.util.Random;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
/**
* 验证码生成器类,可生成数字、大写、小写字母及三者混合类型的验证码。
* 支持自定义验证码字符数量;
* 支持自定义验证码图片的大小;
* 支持自定义需排除的特殊字符;
* 支持自定义干扰线的数量;
* 支持自定义验证码图文颜色
* @author org.javachina
* @version 1.01
*/
public class VerifyCode {
   
    /**
     * 验证码类型为仅数字 0~9
     */
    public static final int TYPE_NUM_ONLY=0;
    /**
     * 验证码类型为仅字母,即大写、小写字母混合
     */
    public static final int TYPE_LETTER_ONLY=1;
   
    /**
     * 验证码类型为数字、大写字母、小写字母混合
     */
    public static final int TYPE_ALL_MIXED=2;
    /**
     * 验证码类型为数字、大写字母混合
     */
    public static final int TYPE_NUM_UPPER=3;        
   
    /**
     * 验证码类型为数字、小写字母混合
     */
    public static final int TYPE_NUM_LOWER=4;   
   
    /**
     * 验证码类型为仅大写字母
     */
    public static final int TYPE_UPPER_ONLY=5;
   
    /**
     * 验证码类型为仅小写字母
     */
    public static final int TYPE_LOWER_ONLY=6;
   
        
    private VerifyCode(){}
    /**
     * 生成验证码字符串
     * @param type 验证码类型,参见本类的静态属性
     * @param length 验证码长度,大于0的整数
     * @param exChars 需排除的特殊字符(仅对数字、字母混合型验证码有效,无需排除则为null)
     * @return 验证码字符串
     */
    public static String generateTextCode(int type,int length,String exChars){
        
        if(length<=0) return "";
        
        StringBuffer code=new StringBuffer();
        int i=0;
        Random r=new Random();
        
        switch(type)
        {
        
        //仅数字
        case TYPE_NUM_ONLY:
            while(i<length){
                int t=r.nextInt(10);
                if(exChars==nullexChars.indexOf(t+"")<0){//排除特殊字符
                    code.append(t);
                    i++;
                }
            }
            break;
            
        //仅字母(即大写字母、小写字母混合)
        case TYPE_LETTER_ONLY:
            while(i<length){
                int t=r.nextInt(123);
                if((t>=97(t>=65&&t<=90))&&(exChars==nullexChars.indexOf((char)t)<0)){
                    code.append((char)t);
                    i++;   
                }
            }
            break;
        
        //数字、大写字母、小写字母混合
        case TYPE_ALL_MIXED:
            while(i<length){
                int t=r.nextInt(123);
                if((t>=97(t>=65&&t<=90)(t>=48&&t<=57))&&(exChars==nullexChars.indexOf((char)t)<0)){
                    code.append((char)t);
                    i++;
                }
            }
            break;   
            
        //数字、大写字母混合
        case TYPE_NUM_UPPER:
            while(i<length){
                int t=r.nextInt(91);
                if((t>=65(t>=48&&t<=57))&&(exChars==nullexChars.indexOf((char)t)<0)){
                    code.append((char)t);
                    i++;
                }
            }
            break;        
            
        //数字、小写字母混合
        case TYPE_NUM_LOWER:
            while(i<length){
                int t=r.nextInt(123);
                if((t>=97(t>=48&&t<=57))&&(exChars==nullexChars.indexOf((char)t)<0)){
                    code.append((char)t);
                    i++;
                }
            }
            break;        
            
        //仅大写字母
        case TYPE_UPPER_ONLY:
            while(i<length){
                int t=r.nextInt(91);
                if((t>=65)&&(exChars==nullexChars.indexOf((char)t)<0)){
                    code.append((char)t);
                    i++;
                }
            }
            break;               
            
        //仅小写字母
        case TYPE_LOWER_ONLY:
            while(i<length){
                int t=r.nextInt(123);
                if((t>=97)&&(exChars==nullexChars.indexOf((char)t)<0)){
                    code.append((char)t);
                    i++;
                }
            }
            break;               
        
        }
        
        return code.toString();
    }
   
    /**
     * 已有验证码,生成验证码图片
     * @param textCode 文本验证码
     * @param width 图片宽度
     * @param height 图片高度
     * @param interLine 图片中干扰线的条数
     * @param randomLocation 每个字符的高低位置是否随机
     * @param backColor 图片颜色,若为null,则采用随机颜色
     * @param foreColor 字体颜色,若为null,则采用随机颜色
     * @param lineColor 干扰线颜色,若为null,则采用随机颜色
     * @return 图片缓存对象
     */
    public static BufferedImage generateImageCode(String textCode,int width,int height,int interLine,
     boolean randomLocation,Color backColor,Color foreColor,Color lineColor){
        
        
        BufferedImage bim=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        Graphics g=bim.getGraphics();
        
        //画背景图
        g.setColor(backColor==null?getRandomColor():backColor);
        g.fillRect(0,0,width,height);
        
        //画干扰线
        Random r=new Random();
        if(interLine>0){
   
            int x=0,y=0,x1=width,y1=0;
            for(int i=0;i<interLine;i++){
                g.setColor(lineColor==null?getRandomColor():lineColor);
                y=r.nextInt(height);
                y1=r.nextInt(height);
   
                g.drawLine(x,y,x1,y1);
            }
        }
        
        //写验证码
        
        //g.setColor(getRandomColor());
        //g.setColor(isSimpleColor?Color.BLACK:Color.WHITE);
        
        //字体大小为图片高度的80%
        int fsize=(int)(height*0.8);
        int fx=height-fsize;
        int fy=fsize;
        g.setFont(new Font(Font.DIALOG,Font.PLAIN,fsize));
        
        //写验证码字符
        for(int i=0;i<textCode.length();i++){
            fy=randomLocation?(int)((Math.random()*0.3+0.6)*height):fy;//每个字符高低是否随机
            g.setColor(foreColor==null?getRandomColor():foreColor);
            g.drawString(textCode.charAt(i)+"",fx,fy);
            fx+=fsize*0.9;
        }
        
        g.dispose();
        
        return bim;
    }
   
   
    /**
     * 生成图片验证码
     * @param type 验证码类型,参见本类的静态属性
     * @param length 验证码字符长度,大于0的整数
     * @param exChars 需排除的特殊字符
     * @param width 图片宽度
     * @param height 图片高度
     * @param interLine 图片中干扰线的条数
     * @param randomLocation 每个字符的高低位置是否随机
     * @param backColor 图片颜色,若为null,则采用随机颜色
     * @param foreColor 字体颜色,若为null,则采用随机颜色
     * @param lineColor 干扰线颜色,若为null,则采用随机颜色
     * @return 图片缓存对象
     */
    public static BufferedImage generateImageCode(int type,int length,String exChars,int width,int height,int interLine,boolean randomLocation,Color backColor,Color foreColor,Color lineColor){
        
        String textCode=generateTextCode(type,length,exChars);
        BufferedImage bim=generateImageCode(textCode,width,height,interLine,randomLocation,backColor,foreColor,lineColor);
        
        return bim;
    }
   
   
    /**
     * 产生随机颜色
     * @return
     */
    private static Color getRandomColor(){
        Random r=new Random();
        Color c=new Color(r.nextInt(255),r.nextInt(255),r.nextInt(255));
        return c;
    }
   
    public static void main(String[] args){
    }
}


4、org.javachina.servlet.VerifyCodeServlet.java 接受客户端请求,向客户端输出验证码
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        //设置浏览器不缓存本页
        response.setHeader("Cache-Control", "no-cache");
        
        //生成验证码,写入用户session
        String verifyCode=VerifyCode.generateTextCode(VerifyCode.TYPE_UPPER_ONLY,4,null);
        request.getSession().setAttribute("verifyCode",verifyCode);
        
        //输出验证码给客户端
        response.setContentType("image/jpeg");
        BufferedImage bim=VerifyCode.generateImageCode(verifyCode, 90, 30, 3,true,Color.WHITE,Color.BLACK,null);
        ImageIO.write(bim, "JPEG",response.getOutputStream());   
        
    }


5、org.javachina.servlet.PubMsgServlet.java 保存留言信息(比对验证码)
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        //得到留言标题、内容及用户输入的验证码
        String msgTitle=request.getParameter("msgTitle");
        String msgContent=request.getParameter("msgContent");
        String verifyCode=request.getParameter("verifyCode");
        
        //取session中的正确验证码
        String legalCode=null;
        if(request.getSession().getAttribute("verifyCode")!=null)
            legalCode=(String)(request.getSession().getAttribute("verifyCode"));
   
        String next;
        
        //比较session中的验证码与用户输入是否一致(这里忽略了大小写)
        if(verifyCode!=null&&verifyCode.equalsIgnoreCase(legalCode)){
            
            /*
             * 保存留言内容(省略)
             */
            
            //指定下一个URL
            next=request.getContextPath()+"/ok.jsp";
            
        }else
            next="this";
        
        response.setContentType("text/plain");
        PrintWriter out = response.getWriter();
        out.print(next);
        out.flush();
        out.close();
        
    }



下载地址:

Java通用验证码程序及应用示例源码下载
回复

使用道具 举报

该用户从未签到

发表于 2012-3-21 18:39:54 | 显示全部楼层
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2012-3-28 00:24:06 | 显示全部楼层
给力
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2012-3-31 17:01:39 | 显示全部楼层
yanzhengma
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2012-4-7 21:44:41 | 显示全部楼层
谢谢了,好好学习一下
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2012-4-27 09:55:31 | 显示全部楼层
新手, 来看看啊。
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2012-5-7 21:21:31 | 显示全部楼层
谢谢楼主分享学习了~
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2012-5-7 21:21:58 | 显示全部楼层
谢谢 分享 学习了~
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2012-5-7 22:10:05 | 显示全部楼层
Font.DIALOG cannot be resolved 有红线 报错 新手求解
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2012-5-15 17:31:06 | 显示全部楼层
收藏收藏
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2025-1-9 07:42 , Processed in 0.441090 second(s), 54 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表