图形验证码(JSP+Servlet)

来源:互联网 发布:android json 编辑:程序博客网 时间:2024/06/05 03:30

图形验证码是各大系统中登录注册模块必备的功能之一,主要用于防止暴力破解。图形验证码的基本原理很简单,可分为以下5步:
(1)建立图形缓冲区
(2)在图形缓冲区上用随机颜色填充背景
(3)在图形缓冲区上输出验证码。
(4)将验证码保存在HttpSession对象中。
(5)向客户输出图形验证码。
废话少说,直接上代码:本例中,通过ValidationCode类实现图形验证码功能,这是一个Servlet类,在客户端只需要向访问普通Servlet一样访问ValidationCode类即可。该类的代码如下:

package servlet;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.io.IOException;import java.io.OutputStream;import java.util.Random;import javax.imageio.ImageIO;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;public class ValidationCode extends HttpServlet{    //图形验证码的字符集    private static String codeChars = "%#23456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";    //返回一个随机三色(color对象)    private static Color getRandomColor(int minColor,int maxColor){        Random random = new Random();        if(minColor>255){            minColor=255;        }        if(maxColor>255){            maxColor=255;        }        //获取红色的随机颜色        int red = minColor +random.nextInt(maxColor-minColor);        int green = minColor +random.nextInt(maxColor-minColor);        int blue = minColor +random.nextInt(maxColor-minColor);        return new Color(red,green,blue);    }    @Override    protected void service(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        //获取验证码集合的长度        int charLength = codeChars.length();        //关闭浏览器的缓冲区        response.setHeader("Pragma", "No-cache");        response.setHeader("Cache-Control", "no-cache");        response.setDateHeader("Expires", 0);        //设置图像验证码的长和宽        int width = 90,height = 20;        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);        //获取Graphics        Graphics g = image.getGraphics();        Random random = new Random();        g.setColor(getRandomColor(180,250));//随机设置要填充的颜色        g.fillRect(0, 0, width, height);//填充图形背景        //设置初始字体        g.setFont(new Font("Times New Roman",Font.ITALIC,height));        g.setColor(getRandomColor(180,250));//随机设置字体颜色        //用于保存最后随机生成的验证码        StringBuilder validationCode = new StringBuilder();        //验证码的随机字体        String[] fontNames = {"Times New Roman","Book antiqua","Arial"};        //随机生成3~5个验证码        for (int i = 0; i < 3+random.nextInt(3); i++) {            //随机设置当前验证码字符的字体            g.setFont(new Font(fontNames[random.nextInt(3)],Font.ITALIC,height));            //随机获取当前验证码的字符            char codeChar = codeChars.charAt(random.nextInt(charLength));            validationCode.append(codeChar);            g.setColor(getRandomColor(10,100));//随机设置字体颜色            //在图形上输出验证码字符,x和y都是随机生成的            g.drawString(String.valueOf(codeChar), 16*i+random.nextInt(7), height-random.nextInt(6));        }        //获得HttpSession对象        HttpSession session = request.getSession();        session.setAttribute("validation_code", validationCode.toString());        //设置session对象5分钟失效        session.setMaxInactiveInterval(5*60);        g.dispose();//关闭Graphics对象        OutputStream os = response.getOutputStream();        //以JPEG格式想客户端发送图形验证码        ImageIO.write(image, "JPEG", os);    }}

上面的代码实现了图形缓冲区颜色的随机变化,图形验证码字符集的自定义,字符个数的自定义(本例为3-5个),字符字体,颜色的随机变化,验证码的过期时间设置等,相当好用。调用该Servlet类时,应该在web.xml进行如下配置:

<servlet>    <servlet-name>ValidationCode</servlet-name>    <servlet-class>servlet.ValidationCode</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>ValidationCode</servlet-name>    <url-pattern>/validation_code</url-pattern>  </servlet-mapping>

很简单,和普通Servlet配置相同,接下来看看在JSP中如何实现验证码的显示,刷新的提交验证吧。。我的register.jsp是这样写的

<form action="register" name="register_form" method="post">……<!--省略了用户名密码等的输入部分--><span class="require">*</span>验证码:<input type="text" id="validation_code" name="validation_code" /><!--验证码输入框--><img src="validation_code" id="img_validation_code"            onclick="refresh()" /><!--图形验证码--><input type="button" value="注册" onclick="checkRegister()" /> </form>    <script type="text/javascript">        function refresh() {            var img = document.getElementById("img_validation_code");            img.src = "validation_code?" + Math.random();        }        //实现验证码的刷新        function checkRegister() {            var validation_code = document.getElementById("validation_code");            if (validation_code.value == "") {                alert("必须输入验证码");                return;            }            register_form.submit();//提交用户信息        }    </script>

在jsp页面上要使用验证码,直接让img的src=”validation_code”(请求上面写好的Servlet:ValidationCode即可),超级方便。那么怎么实现验证呢?本例中form表单的action是register,该Servlet的配置如下

<servlet>    <servlet-name>Register</servlet-name>    <servlet-class>servlet.Register</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>Register</servlet-name>    <url-pattern>/register</url-pattern>  </servlet-mapping>

Register类是怎么实现验证码的验证呢,请看如下代码:

……String validationCode = request.getParameter("validation_code");//获取用户输入验证码if(!checkValidationCode(request, validationCode)){    return;}

checkValidationCode是判断验证码和图片上的验证码是否一致的方法,该方法的具体实现如下

//核对用户验证码是否合法protected boolean checkValidationCode(HttpServletRequest request,String validationCode){//从httpSession对象中获取验证码String validationCodeSession = (String)request.getSession().getAttribute("validation_code");//如果validationCodeSession==null说明验证码过期,要刷新后重新获得验证码if(validationCodeSession==null){//result.jsp需要的结果信息request.setAttribute("info", "验证码过期");return false;}//验证验证码是否正确if(!validationCode.equalsIgnoreCase(validationCodeSession)){//result.jsp需要的结果信息request.setAttribute("info", "验证码不正确");return false;}return true;}

好啦,图形验证码的实现过程就是这样啦,附了一张验证码的图,超赞有木有
这里写图片描述
这里写图片描述

0 0
原创粉丝点击