A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 全海波 中级黑马   /  2012-9-2 15:47  /  3067 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

在JavaWeb中如何生成验证码呢?

评分

参与人数 1技术分 +1 收起 理由
田建 + 1

查看全部评分

5 个回复

倒序浏览
请问楼主是想实现像平时登陆时要输入的验证码吗,如果是的话,我有一个建议,可以简单的实现,平时登陆的验证码,基本上都是图片,你可以自己ps几十张这样的图片,放在webApplication的images文件夹中,图片的文件名设置有规律点,并在后台做好,文件名与图片里的验证码的映射,比如弄个HashMap,key是图片的文件名,value是图片里的验证码。当显示页面时根随机的选择一个图片,依据是文件名,然后设置到页面。放置图片的父标签可以使用div或者span,设置好<image>标签的id,当提交数据时把用户输入的验证码,和用javascript拿到的指定<image>便标签id的的src属性解析字符串搞出来的文件名,一起提交到服务器,服务器端通过文件名拿到map中对应的value,在于提交过来的用户输入的验证码进行比较,把比较信息在传递到前台,进行处理。至于楼主说的随机生成验证码,就转换为了在那一大堆图片中选取一张图片了,算法自己设计吧。
回复 使用道具 举报
给你一段我以前写的代码
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 java.util.*;  
import java.awt.*;  
import java.awt.image.*;  
  
import javax.imageio.*;  
/**
*
* @author mzba
*
*/
public class GetCaptcha extends HttpServlet {  
    private static final long serialVersionUID = 1L;  
  
    /**
     * @see HttpServlet#HttpServlet()
     */  
    public GetCaptcha() {  
        super();  
        // TODO Auto-generated constructor stub  
    }  
  
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */  
    protected void doGet(HttpServletRequest request,  
            HttpServletResponse response) throws ServletException, IOException {  
        response.setContentType("image/jpeg");  
        response.setHeader("Pragma", "No-cache");  
        response.setHeader("Cache-Control", "no-cache");  
        response.setDateHeader("Expires", 0);  
        HttpSession session = request.getSession();  
        // 在内存中创建图象  
        int width = 75, height = 25;  
        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, 24));  
        // 画边框  
        g.setColor(getRandColor(160, 200));  
        g.drawRect(0, 0, width - 1, height - 1);  
        // 随机产生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 + 14, 20);  
        }  
  
        // 将认证码存入SESSION  
        session.setAttribute("vcode", sRand);  
  
        // 图象生效  
        g.dispose();  
        // 输出图象到页面  
        ImageIO.write(image, "JPEG", response.getOutputStream());  
    }  
  
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */  
    protected void doPost(HttpServletRequest request,  
            HttpServletResponse response) throws ServletException, IOException {  
        // TODO Auto-generated method stub  
    }  
  
    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);  
    }  
  
}  

评分

参与人数 1技术分 +1 收起 理由
田建 + 1

查看全部评分

回复 使用道具 举报
这个不错以前用过

当前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;" onkeydown="JavaScript:ifEnter()"/>&nbsp; <img src="/blog/verifyCode.jsp" align="absMiddle" border="0"/> </td>

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

评分

参与人数 1技术分 +1 收起 理由
田建 + 1

查看全部评分

回复 使用道具 举报
什么歌情况 学习了,我以前也写过几个可好长时间没弄过了,都把思维给忘记了。有时间我也找出来更大家分享一下。 呵呵  今天就路过了
回复 使用道具 举报
这个是中级内容了,你可以看看方老师的视频,建议你多学学初级的基础,基础好才是真的好
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马