1、JSP+Servlet生成验证码

通过Jsp和Servlet搭配生成图片验证码并完成验证功能

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>验证码</title>
    <script type="text/javascript">
    /*这里新建一个时间对象来更改求情url,保证每次请求都能生效,浏览器无法缓存  */
    function reloadCode(){
        var time = new Date().getTime();
        document.getElementById("imagecode").src = "servlet/ImageServlet?d="+time;
    }
    </script>
  </head> 
  <body>
  <form action="servlet/LoginServlet" method="get">
    验证码:<input type="text" name="checkcode">
    <img alt="验证码" src="servlet/ImageServlet" id="imagecode">
    <a href="javascript:reloadCode();">看不清楚</a><br>
    <input type="submit" value="提交">
    </form>
  </body>
</html>

java 验证码仿刷 java验证码生成代码_java 验证码仿刷






ImageServlet负责生产随机图片

package checkcode;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
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;

public class ImageServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 这个方法实现验证码的生成
        BufferedImage bi = new BufferedImage(68, 22, BufferedImage.TYPE_INT_RGB);// 创建图像缓冲区
        Graphics g = bi.getGraphics();// 通过缓冲区创建画布
        Color c = new Color(200, 150, 255); //设置图片背景色
        g.setColor(c);
        g.fillRect(0, 0, 68, 22); //画矩形框
        //随机数的char数组,其中容易混淆的已经被剔除
        char[] ch = "23456789ABCDEFGHJKMNPQRSTUVWXYZ".toCharArray(); 
        Random r = new Random();
        int len = ch.length;
        int index;
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 4; i++) {
            index = r.nextInt(len);
            g.setColor(new Color(r.nextInt(88), r.nextInt(188), r.nextInt(255)));
            g.drawString(ch[index] + "", (i * 15) + 3, 18);// 画数字以及数字的位置
            sb.append(ch[index]);
        }
        request.getSession().setAttribute("piccode", sb.toString()); //将生成的随机数放入session中
        ImageIO.write(bi, "jpg", response.getOutputStream()); //输出图片
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}



LoginServlet负责验证

package checkcode;

import java.io.IOException;
import java.io.PrintWriter;

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

public class LoginServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setCharacterEncoding("gbk");
        //从session中取出验证码
        String piccode = (String) request.getSession().getAttribute("piccode");
        //获取用户输入验证码
        String checkcode = request.getParameter("checkcode");
        //忽略大小写
        checkcode = checkcode.toUpperCase();
        PrintWriter out = response.getWriter();
        if (checkcode.equals(piccode)) {
            out.print("验证码输入正确");
        } else {
            out.print("验证码输入错误");
        }
        out.flush();
        out.close();
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

    }

}

至此已经完成了验证码的创建以及验证工作。


2、Jcaptcha组件实现验证码
Jcaptcha:一个用来生成图形验证码的Java开源组件,使用起来非常简便。与Spring搭配可以生成各式各样的验证码。

1、导包

java 验证码仿刷 java验证码生成代码_java_02





2、修改配置文件

<servlet>
            <servlet-name>jcaptcha</servlet-name>
            <servlet-class>com.octo.captcha.module.servlet.image.SimpleImageCaptchaServlet</servlet-class>
    </servlet>
    <servlet>
            <servlet-name>submit</servlet-name>
            <servlet-class>com.octo.captcha.module.servlet.image.sample.SubmitActionServlet</servlet-class>
    </servlet>
    <servlet-mapping>
            <servlet-name>jcaptcha</servlet-name>
            <url-pattern>/jcaptcha.jpg</url-pattern>
    </servlet-mapping>

3、创建index.jsp

<html>
<body>
<h2>Simple Captcha Servlet sample</h2>

<form action="submit.action" method="post">
     <img src="jcaptcha.jpg" /> <input type="text" name="japtcha" value="" />
     <input type="submit"/>
</form>
</body>
</html>

3、创建SubmitActionServlet

package com.octo.captcha.module.servlet.image.sample;

import com.octo.captcha.module.servlet.image.SimpleImageCaptchaServlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SubmitActionServlet extends HttpServlet
{
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
  {
    String userCaptchaResponse = request.getParameter("japtcha");
    boolean captchaPassed = SimpleImageCaptchaServlet.validateResponse(request, userCaptchaResponse);
    if (captchaPassed)
      response.getWriter().write("captcha passed");
    else {
      response.getWriter().write("captcha failed");
    }
    response.getWriter().write("<br/><a href='index.jsp'>Try again</a>");
  }
}

效果图:

java 验证码仿刷 java验证码生成代码_servlet_03


3、Kaptcha组件实现验证码

Kaptcha:一个非常使用的验证码生成工具,可以配置生成各式各样的验证码。

使用过程:

  1. 下载jar包(kaptcha-2.3.jar)
  2. 将jar包导入项目
  3. 编写页面
  4. 配置web.xml
  5. 启动项目

Web.xml配置

<servlet>
    <servlet-name>Kaptcha</servlet-name>
    <servlet-class>
        com.google.code.kaptcha.servlet.KaptchaServlet
    </servlet-class>
</servlet>

<servlet-mapping>
        <servlet-name>Kaptcha</servlet-name>
        <url-pattern>/randomcode.jpg</url-pattern>
    </servlet-mapping>

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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=UTF-8">
<title>randomcode</title>
<script type="text/javascript">
    function changeR(node){
        // 用于点击时产生不同的验证码
        node.src = "randomcode.jpg?time="+new Date().getTime() ;    
    }
</script>
</head>
<body>
<img alt="random" src="randomcode.jpg" onclick="changeR(this)" style="cursor: pointer;">
    <form action="check.jsp">
        <input type="text" name="r">
        <input type="submit" value="提交">
    </form> 
</body>
</html>

此时已经能看到验证码的图片了

check.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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=UTF-8">
<title>check</title>
</head>
<body>
    <%
        // 检查是否是正确的验证码
        //验证码在session中存储的key值,可以在web.xml中配置,也可以使用默认的KAPTCHA_SESSION_KEY
        String k = (String) session
                .getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
        String str = request.getParameter("r");
        if (k.equals(str))
            out.print("true");
        out.print(k + "---" + str);
    %>
</body>
</html>


详细配置

上面讲解的是最简单的使用方法,如果我们需要更绚丽的验证码,就需要进行详细配置。

详细配置是在web.xml中进行初始化参数设置,然后通过复写类的方法完成自定义样式的验证码。

<init-param>
    <description>图片边框,合法值:yes , no</description>
    <param-name>kaptcha.border</param-name>
    <param-value>yes</param-value>
</init-param>


<init-param>
    <description>边框颜色,合法值: r,g,b (and optional alpha) 或者white,black,blue.
    </description>
    <param-name>kaptcha.border.color</param-name>
    <param-value>black</param-value>
</init-param>


<init-param>
    <description>边框厚度,合法值:>0</description>
    <param-name>kaptcha.border.thickness</param-name>
    <param-value>1</param-value>
</init-param>


<init-param>
    <description>图片宽 200</description>
    <param-name>kaptcha.image.width</param-name>
    <param-value>200</param-value>
</init-param>


<init-param>
    <description>图片高 50</description>
    <param-name>kaptcha.image.height</param-name>
    <param-value>50</param-value>
</init-param>


<init-param>
    <description>图片实现类</description>
    <param-name>kaptcha.producer.impl</param-name>
    <param-value>com.google.code.kaptcha.impl.DefaultKaptcha
    </param-value>
</init-param>


<init-param>
    <description>文本实现类</description>
    <param-name>kaptcha.textproducer.impl</param-name>
    <param-value>com.google.code.kaptcha.text.impl.DefaultTextCreator
    </param-value>
</init-param>


<init-param>
    <description>文本集合,验证码值从此集合中获取</description>
    <paramname>kaptcha.textproducer.char.string</param-name>
    <param-value>1234567890</param-value>
</init-param>


<init-param>
    <description>验证码长度 5</description>
    <param-name>kaptcha.textproducer.char.length</param-name>
    <param-value>2</param-value>
</init-param>


<init-param>
    <description>字体 Arial, Courier</description>
    <param-name>kaptcha.textproducer.font.names</param-name>
    <param-value>Arial, Courier</param-value>
</init-param>


<init-param>
    <description>字体大小 40px.</description>
    <param-name>kaptcha.textproducer.font.size</param-name>
    <param-value>40</param-value>
</init-param>


<init-param>
    <description>
        字体颜色,合法值: r,g,b 或者 white,black,blue.
    </description>
    <param-name>kaptcha.textproducer.font.color</param-name>
    <param-value>black</param-value>
</init-param>


<init-param>
    <description>文字间隔 2</description>
    <param-name>kaptcha.textproducer.char.space</param-name>
    <param-value>2</param-value>
</init-param>


<init-param>
    <description>干扰实现类</description>
    <param-name>kaptcha.noise.impl</param-name>
    <param-value>
        <!-- com.google.code.kaptcha.impl.NoNoise -->
        com.google.code.kaptcha.impl.DefaultNoise
    </param-value>
</init-param>


<init-param>
    <description>
        干扰颜色,合法值: r,g,b 或者 white,black,blue.
    </description>
    <param-name>kaptcha.noise.color</param-name>
    <param-value>black</param-value>
</init-param>


<init-param>
    <description>
        图片样式: 水纹com.google.code.kaptcha.impl.WaterRipple
        鱼眼com.google.code.kaptcha.impl.FishEyeGimpy
        阴影com.google.code.kaptcha.impl.ShadowGimpy
    </description>
    <param-name>kaptcha.obscurificator.impl</param-name>
    <param-value>
        com.google.code.kaptcha.impl.WaterRipple
    </param-value>
</init-param>


<init-param>
    <description>背景实现类</description>
    <param-name>kaptcha.background.impl</param-name>
    <param-value>
        com.google.code.kaptcha.impl.DefaultBackground
    </param-value>
</init-param>


<init-param>
    <description>背景颜色渐变,开始颜色</description>
    <param-name>kaptcha.background.clear.from</param-name>
    <param-value>green</param-value>
</init-param>


<init-param>
    <description>背景颜色渐变,结束颜色</description>
    <param-name>kaptcha.background.clear.to</param-name>
    <param-value>white</param-value>
</init-param>


<init-param>
    <description>文字渲染器</description>
    <param-name>kaptcha.word.impl</param-name>
    <param-value>
        com.google.code.kaptcha.text.impl.DefaultWordRenderer
    </param-value>
</init-param>


<init-param>
    <description>
        session中存放验证码的key键
    </description>
    <param-name>kaptcha.session.key</param-name>
    <param-value>KAPTCHA_SESSION_KEY</param-value>
</init-param>


<init-param>
    <description>
        The date the kaptcha is generated is put into the HttpSession. This is the key value for that item in the session.
    </description>
    <param-name>kaptcha.session.date</param-name>
    <param-value>KAPTCHA_SESSION_DATE</param-value>
</init-param>


中文验证码

中文验证码的实现仿照jar包中提供的文本生成类,需要继承Configurable(读取配置信息)并且实现TextProducer接口(文本生成接口)
ChineseText

package bqh.cslg;

import java.util.Random;

import com.google.code.kaptcha.text.TextProducer;
import com.google.code.kaptcha.util.Configurable;

public class ChineseText extends Configurable implements TextProducer {

    /**
     * 中文实例
     * 
     * @return
     */
    public String getText() {
        int length = getConfig().getTextProducerCharLength();
        String finalWord = "", firstWord = "";
        int tempInt = 0;
        String[] array = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
                "a", "b", "c", "d", "e", "f" };

        Random rand = new Random();

        for (int i = 0; i < length; i++) {
            switch (rand.nextInt(array.length)) {
            case 1:
                tempInt = rand.nextInt(26) + 65;
                firstWord = String.valueOf((char) tempInt);
                break;
            case 2:
                int r1,
                r2,
                r3,
                r4;
                String strH,
                strL;// high&low
                r1 = rand.nextInt(3) + 11; // 前闭后开[11,14)
                if (r1 == 13) {
                    r2 = rand.nextInt(7);
                } else {
                    r2 = rand.nextInt(16);
                }

                r3 = rand.nextInt(6) + 10;
                if (r3 == 10) {
                    r4 = rand.nextInt(15) + 1;
                } else if (r3 == 15) {
                    r4 = rand.nextInt(15);
                } else {
                    r4 = rand.nextInt(16);
                }

                strH = array[r1] + array[r2];
                strL = array[r3] + array[r4];

                byte[] bytes = new byte[2];
                bytes[0] = (byte) (Integer.parseInt(strH, 16));
                bytes[1] = (byte) (Integer.parseInt(strL, 16));

                firstWord = new String(bytes);
                break;
            default:
                tempInt = rand.nextInt(10) + 48;
                firstWord = String.valueOf((char) tempInt);
                break;
            }
            finalWord += firstWord;
        }
        return finalWord;
    }
}

同样需要修改配置文件web.xml

<init-param>
    <description>文本实现类</description>
    <param-name>kaptcha.textproducer.impl</param-name>
    <param-value>
        <!-- com.google.code.kaptcha.text.impl.DefaultTextCreator -->
        <!-- com.google.code.kaptcha.text.impl.FiveLetterFirstNameTextCreator -->
        <!-- com.google.code.kaptcha.text.impl.ChineseTextProducer -->
        bqh.cslg.ChineseText
    </param-value>
</init-param>


算式验证码

要实现算式验证码,需要一下几步:

  1. 获取随机数值,并相加
  2. 将计算公式写到验证码图片中
  3. 将结果保存到session中

为此需要重写KaptchaServlet来完成算式验证码逻辑

KaptchaServlet

import com.google.code.kaptcha.Producer;
import com.google.code.kaptcha.util.Config;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;
import javax.imageio.ImageIO;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class KaptchaServlet extends HttpServlet implements Servlet {
    private Properties props;
    private Producer kaptchaProducer;
    private String sessionKeyValue;

    public KaptchaServlet() {
        this.props = new Properties();

        this.kaptchaProducer = null;

        this.sessionKeyValue = null;
    }

    public void init(ServletConfig conf) throws ServletException {
        super.init(conf);

        ImageIO.setUseCache(false);

        Enumeration initParams = conf.getInitParameterNames();
        while (initParams.hasMoreElements()) {
            String key = (String) initParams.nextElement();
            String value = conf.getInitParameter(key);
            this.props.put(key, value);
        }

        Config config = new Config(this.props);
        this.kaptchaProducer = config.getProducerImpl();
        this.sessionKeyValue = config.getSessionKey();
    }

    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setDateHeader("Expires", 0L);

        resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");

        resp.addHeader("Cache-Control", "post-check=0, pre-check=0");

        resp.setHeader("Pragma", "no-cache");

        resp.setContentType("image/jpeg");

        String capText = this.kaptchaProducer.createText();
        String s1 = capText.substring(0, 1);
        String s2 = capText.substring(1, 2);
        int r = Integer.valueOf(s1).intValue() + Integer.valueOf(s2).intValue();

        req.getSession().setAttribute(this.sessionKeyValue, String.valueOf(r));

        BufferedImage bi = this.kaptchaProducer.createImage(s1+"+"+s2+"=?");

        ServletOutputStream out = resp.getOutputStream();

        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
    }
}

完成之后需要修改web.xml

<servlet-class>
    <!--这里的路径为自定义servlet路径 -->
    KaptchaServlet
</servlet-class>


<init-param>
    <description>文本实现类</description>
    <param-name>kaptcha.textproducer.impl</param-name>
    <param-value>
        com.google.code.kaptcha.text.impl.DefaultTextCreator
    </param-value>
</init-param>


<init-param>
    <description>文本集合,验证码值从此集合中获取</description>
    <param-name>kaptcha.textproducer.char.string</param-name>
    <param-value>0123456789</param-value>
</init-param>

以上就是我总结的3中Java验证码实现方法,各有优势把。