• 生成验证码的几种方式


    生成验证码的几种方式

    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>
  • 相关阅读:
    NBUT 1120 Reimu's Teleport (线段树)
    NBUT 1119 Patchouli's Books (STL应用)
    NBUT 1118 Marisa's Affair (排序统计,水)
    NBUT 1117 Kotiya's Incantation(字符输入处理)
    NBUT 1115 Cirno's Trick (水)
    NBUT 1114 Alice's Puppets(排序统计,水)
    188 Best Time to Buy and Sell Stock IV 买卖股票的最佳时机 IV
    187 Repeated DNA Sequences 重复的DNA序列
    179 Largest Number 把数组排成最大的数
    174 Dungeon Game 地下城游戏
  • 原文地址:https://www.cnblogs.com/lizm166/p/10113701.html
Copyright © 2020-2023  润新知