the5fire

关注Python、Django、Vim、Linux、Web开发、团队管理和互联网--Life is short, we need Python.


Servlet生成数字验证码及判断

作者:the5fire | 标签:   | 发布:2011-01-06 5:16 p.m. | 阅读量: 8119, 8008

为了提高网站的安全性,或者软件的安全性,现在再输入用户名和密码进行网站或者软件登陆的时候,如果输错一次就会出现输入验证码这一项,主要是为了保护账号不被暴力破解。这里我简单实现一下验证码。 使用Servlet生成验证码部分是摘自javaeye,有现成的代码直接使用就好了。不过前台这块纠结了半天,本来是打算用js对输入的验证码进行判断结果发现实现不了。最后只能写jsp脚本实现了。 首先是Servlet代码:SimpleCaptchaServlet.java:

package com.web;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.*;

/**
 * 生成验证码的Servlet
 * @author 胡阳
 * 注:该代码参考自javaeye
 *
 */
public class SimpleCaptchaServlet extends HttpServlet {

    public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException
    {
            res.setContentType("image/jpeg");
            res.setHeader("Pragma","No-cache");
            res.setHeader("Cache-Control","no-cache");
            res.setDateHeader("Expires", 0);
            HttpSession session = req.getSession(true);

            // 在内存中创建图象
            int width=60, height=20;
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

            // 获取图形上下文
            Graphics g = image.getGraphics();

            // 生成随机类
            Random random = new Random();

            // 设定背景色
            g.setColor(getRandColor(200,250));
            g.fillRect(0, 0, width, height);

            // 设定字体
            g.setFont(new Font("Times New Roman",Font.PLAIN,18));

            // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
            g.setColor(getRandColor(160,200));
            for (int i=0;i<155;i++)
            {
                    int x = random.nextInt(width);
                    int y = random.nextInt(height);
                    int xl = random.nextInt(12);
                    int yl = random.nextInt(12);
                    g.drawLine(x,y,x+xl,y+yl);
            }

            // 取随机产生的认证码(4位数字)
            String sRand="";
            for (int i=0;i<4;i++)
            {
                String rand=String.valueOf(random.nextInt(10));
                sRand+=rand;
                // 将认证码显示到图象中
                g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
                    // 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
                g.drawString(rand,13*i+6,16);
            }

            // 将认证码存入SESSION
            session.setAttribute("VerifyCode",sRand);

            // 图象生效
            g.dispose();

            // 输出图象到页面
            ImageIO.write(image, "JPEG", res.getOutputStream());
            //JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(res.getOutputStream());
            //encoder.encode(image);
    }

    public void doPost(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException
    {
            doGet(req,res);
    }

    //给定范围获得随机颜色
    private Color getRandColor(int fc,int bc)
    {
            Random random = new Random();
            if(fc>255) fc=255;
            if(bc>255) bc=255;
            int r=fc+random.nextInt(bc-fc);
            int g=fc+random.nextInt(bc-fc);
            int b=fc+random.nextInt(bc-fc);
            return new Color(r,g,b);
    }
}

然后配置xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>SimpleCaptchaServlet</servlet-name>
        <servlet-class>com.web.SimpleCaptchaServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SimpleCaptchaServlet</servlet-name>
        <url-pattern>/servlet/SimpleCaptchaServlet</url-pattern>
    </servlet-mapping>
</web-app>

最后index.jsp页面:

<%@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding="GB18030"%>
<%
    String verifyCode = (String)session.getAttribute("VerifyCode");
    String command = request.getParameter("command");
    String anthCode = request.getParameter("authCode");

    if ("ok".equalsIgnoreCase(command)) {
        if (anthCode != null && anthCode.equalsIgnoreCase(verifyCode)) {
            out.print("测试成功!");
        } else{
            out.println("验证码错误!");
        }

    }

%>
<!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=GB18030">
<title>Insert title here</title>
<script language=JavaScript>
    function change(field) {
        /*采用ajax的话可以使用这个代码,另外还需要从服务器端得到当前验证码
        var timenow = new Date().getTime();
        field.src="servlet/SimpleCaptchaServlet?d=" + timenow;
        */
        document.URL=location.href;
    }

</script>
</head>
<body>
    <form action="index.jsp">
        <input type="hidden" name="command" value="ok">
        <input id="authCode" name="authCode" type="text" size="6" maxlength="4">
        <img src="servlet/SimpleCaptchaServlet" alt="验证码" onClick="change(this);">
        <input name="ok" type="submit" value="确定">
    </form>
</body>
</html>

比较简单。

—EOF—

- from the5fire.com
----EOF-----

微信公众号:Python程序员杂谈


其他分类: