java web应用中验证码的生成方法.

当前web应用越来越注重安全性的问题,所以再web应用项目实施中,用到了验证码的机制,其目的就是建立防刷机制,限制用户恶意提交页面,保护系统.

现在网络上各个网站上都有验证码,但是实现的形形色色各不相同.通过查资料和摸索,使用servlet来实现验证码.

一 建一个验证码生成类RandomImageGenerator ,其功能就是实现验证码

该类实现如下

import java.awt.*;
import java.awt.image.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import org.apache.commons.lang.RandomStringUtils;

/**
 * 随即图片生成器
 * 该类用于用户注册时候需要用户根据图片内容进行填写正确后方可注册
 * @author Liudong
 */
public class RandomImageGenerator {

//随即生成包含验证码的字符串   

public static String random() {
        //20060320 add by wyx
        //因为o和0,l和1很难区分,所以,去掉大小写的o和l

        String str = "";
        str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz";//初始化种子
        return RandomStringUtils.random(6, str);//返回6为的字符串
            }

    /**
     * 根据要求的数字生成图片,背景为白色,字体大小16,字体颜色黑色粗体
     * @param num 要生成的数字
     * @param out 输出流
     * @throws IOException
     */
    public static void render(String num, OutputStream out) throws IOException {
        if (num.getBytes().length > 6) {
            throw new IllegalArgumentException(
                    "The length of param num cannot exceed 6.");
        }
        //设定宽度和高度
        int width = 130; 

        int height = 30; 
        // 在内存中创建图象
        BufferedImage bi = new BufferedImage(width, height,
                                             BufferedImage.TYPE_INT_RGB);
        // 获取图形上下文
        Graphics2D g = (Graphics2D) bi.getGraphics();
        //画边框
        java.util.Random random = new java.util.Random();
        g.setColor(Color.white);
        g.fillRect(0, 0, width, height);
        //设置字体
        Font mFont = new Font("Tahoma", Font.BOLD, 16);
        g.setFont(mFont);
        g.setColor(Color.BLACK);//设置字体颜色
        //画认证码,每个认证码在不同的水平位置
        String str1[] = new String[6];
        for (int i = 0; i < str1.length; i++) {
            str1[i] = num.substring(i, i + 1);
            int w = 0;
            int x = (i + 1) % 3;

//随即生成验证码字符的水平偏移量
            if (x == random.nextInt(3)) {
                w = 19 - random.nextInt(7);
            } else {
                w = 19 + random.nextInt(7);
            }

//随即生成颜色
            Color color1 = new Color(random.nextInt(180), random.nextInt(180),
                                     random.nextInt(180));
            g.setColor(color1);
            g.drawString(str1[i], 20 * i + 10, w);
        }

        // 随机产生干扰点,并用不同的颜色表示,使图象中的认证码不易被其它程序探测到
        for (int i = 0; i < 100; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            Color color1 = new Color(random.nextInt(255), random.nextInt(255),
                                     random.nextInt(255));
            g.setColor(color1); //随即画各种颜色的点
            g.drawOval(x, y, 0, 0);
        }
        //画干扰线
        for (int i = 0; i < 5; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int x1 = random.nextInt(width);
            int y1 = random.nextInt(height);
            Color color1 = new Color(random.nextInt(255), random.nextInt(255),
                                     random.nextInt(255));

            g.setColor(color1); //随即画各种颜色的线
            g.drawLine(x, y, x1, y1);
        }
        //图像生效
        g.dispose();
        //输出页面
        ImageIO.write(bi, "jpg", out);
    }

    public static void main(String[] args) throws IOException {
        String num = random();
        System.out.println(num);
        render(num, new FileOutputStream("D://test.jpg"));
        System.out.println("Image generated.");
    }
}

二 验证码的实现,使用servlet来实现验证码

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import peopleBlog.util.RandomImageGenerator;


/**
 * 用于产生随即图片以防止非法攻击
 * @author Liudong
 */
public class RandomImageServlet extends HttpServlet {
 public final static String RANDOM_LOGIN_KEY = "RANDOM_LOGIN_KEY";

 public void init() throws ServletException {
  System.setProperty("java.awt.headless","true");
 }

    public static String getRandomLoginKey(HttpServletRequest req) {
        return (String)req.getSession().getAttribute(RANDOM_LOGIN_KEY);
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
    {
        HttpSession ssn = req.getSession();
        if(ssn!=null) {
            String randomString = RandomImageGenerator.random();//生成种子
            ssn.setAttribute(RANDOM_LOGIN_KEY,randomString);//将种子放到session里面
            res.setContentType("image/jpeg");//设置图像生成格式

            RandomImageGenerator.render(randomString,res.getOutputStream());//输出到页面
        }
    }
}

其中 ssn.setAttribute(RANDOM_LOGIN_KEY,randomString);这一行代码的作用是:

当从页面上输入验证码,提交后,在后台sevlet或者action里面验证输入的验证码和session里面的是否一致,如果不一致返回错误信息.

三,页面实现

在web.xml文件中设置

<servlet>
    <servlet-name>image</servlet-name>
    <servlet-class>peopleBlog.RandomImageServlet</servlet-class>
    <load-on-startup>5</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>image</servlet-name>
    <url-pattern>/verifyCode.jsp</url-pattern>

  </servlet-mapping>

然后在jsp页面中

        <td><input name="verifyCode" type="text" id="verifyCode" class="input2" style="width:55px;" οnkeydοwn="JavaScript:ifEnter()"/>&nbsp; <img src="/blog/verifyCode.jsp" align="absMiddle" border="0"/> </td>

再在目的servlet中进行验证码判断就ok了

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值