生成验证码的几种方式详解程序员

生成验证码的几种方式

1,在jsp页面中直接生成验证码

image.jsp源码:

//image.jsp 
<%@ page contentType="image/jpeg" 
    import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" 
    pageEncoding="GBK"%> 
<%!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); 
    }%> 
<% 
    //设置页面不缓存 
    response.setHeader("Pragma", "No-cache"); 
    response.setHeader("Cache-Control", "no-cache"); 
    response.setDateHeader("Expires", 0); 
    // 在内存中创建图象 
    // 通过这里可以修改图片大小 
    int width = 85, height = 23; 
    BufferedImage image = new BufferedImage(width, height, 
            BufferedImage.TYPE_INT_RGB); 
    // 获取图形上下文 
    // g相当于笔 
    Graphics g = image.getGraphics(); 
    //生成随机类 
    Random random = new Random(); 
    // 设定背景色 
    g.setColor(getRandColor(200, 250)); 
    // 画一个实心的长方,作为北京 
    g.fillRect(0, 0, width, height); 
    //设定字体 
    g.setFont(new Font("黑体", Font.PLAIN, 18)); 
    //画边框 
    g.setColor(Color.BLUE); 
    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 rand = request.getParameter("rand"); 
    //rand = rand.substring(0,rand.indexOf(".")); 
    String sRand = ""; 
    // 如果要使用中文,必须定义字库,可以使用数组进行定义 
    // 这里直接写中文会出乱码,必须将中文转换为unicode编码 
    String[] str = { "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", 
            "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", 
            "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", 
            "k", "m", "n", "p", "s", "t", "u", "v", "w", "x", "y", "z", 
            "1", "2", "3", "4", "5", "6", "7", "8", "9" }; 
    for (int i = 0; i < 5; i++) { 
        String rand = str[random.nextInt(str.length)]; 
        sRand += rand; 
        // 将认证码显示到图象中 
        g.setColor(new Color(20 + random.nextInt(110), 20 + random 
                .nextInt(110), 20 + random.nextInt(110)));//调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成 
        g.drawString(rand, 16 * i + 6, 19); 
    } 
    // 将认证码存入SESSION 
    session.setAttribute("rand", sRand); 
    // 图象生效 
    g.dispose(); 
    // 输出图象到页面 
    ImageIO.write(image, "JPEG", response.getOutputStream()); 
    out.clear(); 
    out = pageContext.pushBody(); 
%>

login.jsp源码(使用验证码的页面):

//使用验证码的页面login.jsp 
<%@ page contentType="text/html" pageEncoding="GBK"%> 
<html> 
    <head> 
        <title>登陆页面</title> 
        <script> 
    function reloadImage() {  
        document.getElementById('identity').src = 'image.jsp?ts=' + new Date() 
                .getTime(); 
    } 
</script> 
    </head> 
    <body> 
        <center> 
            <% 
                // 乱码解决 
                request.setCharacterEncoding("GBK"); 
            %> 
            <h1> 
                登陆程序 
            </h1> 
            <hr> 
            <%=request.getAttribute("info") != null ? request 
                    .getAttribute("info") : ""%> 
            <form action="check.jsp" method="post"> 
                用户ID: 
                <input type="text" name="mid"> 
                <br> 
                密  码: 
                <input type="password" name="password"> 
                <br> 
                验证码: 
                <input type="text" name="code"  maxlength="5" size="5"> 
                <img src="image.jsp" id="identity" onclick="reloadImage()" title="看不清,点击换一张"> 
                <br> 
                <input type="submit" value="登陆"> 
                <input type="reset" value="重置"> 
            </form> 
        </center> 
    </body> 
</html>

效果如下:

生成验证码的几种方式详解程序员

2,使用Servlet生成验证码

IdentityServlet.java源码:

//IdentityServlet.java代码如下: 
package com.helloweenvsfei.servlet; 
import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics2D; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.util.Random; 
import javax.servlet.ServletException; 
import javax.servlet.ServletOutputStream; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse;  
import com.sun.image.codec.jpeg.JPEGCodec; 
import com.sun.image.codec.jpeg.JPEGImageEncoder;  
public class IdentityServlet extends HttpServlet { 
    /** 
     *  
     */ 
    private static final long serialVersionUID = -479885884254942306L; 
    public static final char[] CHARS = { '2', '3', '4', '5', '6', '7', '8', 
            '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 
            'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; 
  
    public static Random random = new Random(); 
    public static String getRandomString() { 
        StringBuffer buffer = new StringBuffer(); 
        for (int i = 0; i < 6; i++) { 
            buffer.append(CHARS[random.nextInt(CHARS.length)]); 
        } 
        return buffer.toString(); 
    } 
    public static Color getRandomColor() { 
        return new Color(random.nextInt(255), random.nextInt(255), random 
                .nextInt(255)); 
    } 
    public static Color getReverseColor(Color c) { 
        return new Color(255 - c.getRed(), 255 - c.getGreen(), 255 - c 
                .getBlue()); 
    } 
    public void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException { 
  
        response.setContentType("image/jpeg"); 
        String randomString = getRandomString(); 
        request.getSession(true).setAttribute("randomString", randomString); 
        int width = 100; 
        int height = 30; 
        Color color = getRandomColor(); 
        Color reverse = getReverseColor(color); 
        BufferedImage bi = new BufferedImage(width, height, 
                BufferedImage.TYPE_INT_RGB); 
        Graphics2D g = bi.createGraphics(); 
        g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16)); 
        g.setColor(color); 
        g.fillRect(0, 0, width, height); 
        g.setColor(reverse); 
        g.drawString(randomString, 18, 20); 
        for (int i = 0, n = random.nextInt(100); i < n; i++) { 
            g.drawRect(random.nextInt(width), random.nextInt(height), 1, 1); 
        } 
        // 转成JPEG格式 
        ServletOutputStream out = response.getOutputStream(); 
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 
        encoder.encode(bi); 
        out.flush(); 
    } 
    public static void main(String[] args) { 
        System.out.println(getRandomString()); 
    } 
}

Web..xml源码:

//Web.xml的配置为: 
<servlet> 
    <servlet-name>IdentityServlet</servlet-name> 
    <servlet-class>com.helloweenvsfei.servlet.IdentityServlet</servlet-class> 
</servlet> 
<servlet-mapping> 
    <servlet-name>IdentityServlet</servlet-name> 
    <url-pattern>/servlet/IdentityServlet</url-pattern> 
</servlet-mapping>

identity.html源码:

//测试页面identity.html为: 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html> 
    <head> 
        <title>identity.html</title> 
  
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 
        <meta http-equiv="description" content="this is my page"> 
        <meta http-equiv="content-type" content="text/html; charset=GB18030"> 
  
        <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> 
  
    </head> 
  
    <body> 
  
<script> 
    function reloadImage() { 
        document.getElementById('btn').disabled = true; 
        document.getElementById('identity').src='servlet/IdentityServlet?ts=' + new Date().getTime(); 
    } 
    </script> 
  
        <img src="servlet/IdentityServlet" id="identity" onload="btn.disabled = false; " /> 
        <input type=button value=" 换个图片 " onclick="reloadImage()" id="btn"> 
  
    </body> 
</html>

3,在Struts2应用中生成验证码

RandomNumUtil.java源码:

//RandomNumUtil.java 
package org.ml.util; 
import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.image.BufferedImage; 
import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.util.Random; 
import javax.imageio.ImageIO; 
import javax.imageio.stream.ImageOutputStream; 
public class RandomNumUtil { 
public static final char[] CHARS = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 
'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z','2', '3', '4', '5', '6', '7', '8', 
'9','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 
'n', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};  
private ByteArrayInputStream image;// 图像 
private String str;// 验证码 
/** 
*  构造方法调用初始化属性方法 
*/ 
private RandomNumUtil() { 
init(); 
} 
/** 
* 取得RandomNumUtil实例 
*/ 
public static RandomNumUtil Instance() { 
return new RandomNumUtil(); 
} 
/** 
* 取得验证码图片 
*/ 
public ByteArrayInputStream getImage() { 
return this.image; 
} 
/** 
* 取得图片的验证码 
*/ 
public String getString() { 
return this.str; 
}    
/** 
* 初始化属性否具体方法 
*/ 
private void init() { 
// 在内存中创建图象 
int width = 85, height = 18; 
//设置图形的高度和宽度,以及RGB类型 
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)); 
// 随机产生255条干扰线,使图象中的认证码不易被其它程序探测到 
g.setColor(getRandColor(160, 200)); 
for (int i = 0; i < 255; 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); 
} 
// 取随机产生的认证码(6位数字) 
StringBuffer sRand = new StringBuffer();   
for (int i = 0; i < 6; i++) { 
String rand = String.valueOf(CHARS[random.nextInt(CHARS.length-1)]);//从字符数组中随机产生一个字符 
            sRand.append(rand);  
// 将认证码显示到图象中 
g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110))); 
// 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成 
g.drawString(rand, 13 * i + 6, 17); 
} 
// 赋值验证码 
this.str = sRand.toString(); 
// 图象生效 
        g.dispose(); 
//下面将生成的图形转变为图片 
ByteArrayOutputStream output = new ByteArrayOutputStream();  
ByteArrayInputStream input = null; 
try { 
ImageOutputStream imageOut = ImageIO.createImageOutputStream(output); 
ImageIO.write(image, "JPEG", imageOut);//将图像按JPEG格式写入到imageOut中,即存入到output的字节流中 
imageOut.close();//关闭写入流 
input = new ByteArrayInputStream(output.toByteArray());//input读取output中的图像信息 
} catch (Exception e) { 
System.out.println("验证码图片产生出现错误:" + e.toString()); 
} 
this.image = input;/* 赋值图像 */ 
}  
/* 
* 给定范围获得随机颜色 
*/ 
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); 
} 
}

RandomAction.java源码:

//RandomAction.java的代码: 
package org.ml.action; 
import java.io.ByteArrayInputStream; 
import org.ml.util.RandomNumUtil; 
import com.opensymphony.xwork2.ActionContext; 
import com.opensymphony.xwork2.ActionSupport; 
@SuppressWarnings("serial") 
public class RandomAction extends ActionSupport { 
private ByteArrayInputStream inputStream; 
public String execute() throws Exception { 
RandomNumUtil rdnu = RandomNumUtil.Instance();//取得随机验证码产生类的对象 
this.setInputStream(rdnu.getImage());// 取得带有随机字符串的图片 
ActionContext.getContext().getSession().put("random", rdnu.getString());// 取得随机字符串放入HttpSession 
return SUCCESS; 
} 
public void setInputStream(ByteArrayInputStream inputStream) { 
this.inputStream = inputStream; 
} 
public ByteArrayInputStream getInputStream() { 
return inputStream; 
} 
}

struts.xml配置:

//struts.xml配置为: 
<!-- Random验证码 --> 
<action name="rand" class="org.ml.action.RandomAction"> 
<result type="stream" name="success"> 
<param name="contentType">image/JPEG</param> 
<param name="inputName">inputStream</param> 
</result> 
</action>

HTML中的表单源码:

//HTML中的表单代码为: 
<tr  height="35" > 
<td width="14%" class="top_hui_text"> 
<span class="login_txt"> 验证码:    </span> 
</td> 
<td colspan="2" class="top_hui_text"> 
<input type="text" name="rand" id="rand" size="6" 
maxlength="6"> 
<script type="text/javascript">  
function changeValidateCode(obj) {  
//获取当前的时间作为参数,无具体意义  
var timenow = new Date().getTime();  
//每次请求需要一个不同的参数,否则可能会返回同样的验证码  
//这和浏览器的缓存机制有关系,也可以把页面设置为不缓存,这样就不用这个参数了。  
   obj.src="rand.action?d="+timenow;  
}  
</script> 
<img src="rand.action" title="点击图片刷新验证码" 
onclick="changeValidateCode(this)" height="22" 
width="80" /> 
</td>  
</tr>

 

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/2552.html

(0)
上一篇 2021年7月16日
下一篇 2021年7月16日

相关推荐

发表回复

登录后才能评论