web 页面 验证码 实现

1. 前台页面代码:  页面刷新时会自动请求 ${pageContext.request.contextPath}/yanzheng?yz=&time=-1111 这个action

<form name="f" action="" method="post">
        用户名 : <input id="name" type="text" name="userDTO.userName" /><br>
        密    码 : <input  type="password" name="userDTO.passWord" /><br>
        验证码 : <input  type="checkCode" name="userDTO.checkCode" /><br>
        <img id="myzmDiv" src="${pageContext.request.contextPath}/yanzheng?yz=&time=-1111" onClick="yanZhengMa()" style="width: 80px; height: 40px; border-radius: 4px">
        <input type="button" value="submit1" onclick="javascript:document.f.action='user/login';document.f.submit();" />
    </form>

<!-- 点击图片同样请求这个 action 进行刷新验证码,  需要传入一个当前时间戳,  避免缓存不更新,   变量yz没用,  懒得删 -->
<script type="text/javascript">
    function yanZhengMa(){
        var yz = "";
        $("#myzmDiv").attr("src","${pageContext.request.contextPath}/yanzheng?yz="+yz+"&time="+new Date());
    }
</script>

2. struts.xml配置文件   不需要result标签返回,   会自动返回到 请求页面

  <package name="user2" namespace="/" extends="struts-default"> 
        <action name="yanzheng" class="com.test.actions.YanzhengAction" method="yanzhengma" />
    </package>

3.  yanzhengma   方法实现   会将随机生成的数字图片发回到请求页面,  并且会将生成的数字存储到 session中, key 和 value 都是生成的随机数

public String yanzhengma() throws IOException {
        //"{\"code\":501,\"info\":\"已经在业务中使用,不能删除\"}";
        HttpSession session = ServletActionContext.getRequest().getSession();
        String code="";
        Captcha cha=new SpecCaptcha();
        char[] shu=cha.alphas();
        for(int i=0;i<shu.length;i++){
            code+=shu[i]+"";
        }
        Captcha captcha = new SpecCaptcha(58,28,4,shu);// gif格式动画验证码  
        HttpServletResponse response = ServletActionContext.getResponse();
        ServletOutputStream out = response.getOutputStream();
        captcha.out(out);
        session.setAttribute(code, code);
        out.flush();
        out.close();
        return null;
    }

  3-1 >    附属类: Captcha.java

package com.test.Util;


import java.awt.Color;
import java.awt.Font;
import java.io.OutputStream;

public abstract class Captcha
{
    protected Font font = new Font("Verdana", Font.ITALIC|Font.BOLD, 18);   // 字体
    protected int len = 4;  // 验证码随机字符长度
    protected int width = 78;  // 验证码显示跨度
    protected int height = 30;  // 验证码显示高度
    private String chars = null;  // 随机字符串
    protected char[] shu;
    /**
     * 生成随机字符数组
     * @return 字符数组
     */
    public char[] alphas()
    {
        char[] cs = new char[len];
        for(int i = 0;i<len;i++)
        {
            cs[i] = Randoms.alpha();
        }
        chars = new String(cs);
    return cs;
    }
    public Font getFont()
    {
        return font;
    }
 
    public void setFont(Font font)
    {
        this.font = font;
    }
 
    public int getLen()
    {
        return len;
    }
 
    public void setLen(int len)
    {
        this.len = len;
    }
 
    public int getWidth()
    {
        return width;
    }
 
    public void setWidth(int width)
    {
        this.width = width;
    }
 
    public int getHeight()
    {
        return height;
    }
 
    public void setHeight(int height)
    {
        this.height = height;
    }
 
    public String getChars() {
        return chars;
    }
    public void setChars(String chars) {
        this.chars = chars;
    }
    public char[] getShu() {
        return shu;
    }
    public void setShu(char[] shu) {
        this.shu = shu;
    }
    /**
     * 给定范围获得随机颜色
     * @return Color 随机颜色
     */
    protected Color color(int fc, int bc)
    {
        if (fc > 255)
            fc = 255;
        if (bc > 255)
            bc = 255;
        int r = fc + Randoms.num(bc - fc);
        int g = fc + Randoms.num(bc - fc);
        int b = fc + Randoms.num(bc - fc);
        return new Color(r, g, b);
    }
    /**
     * 验证码输出,抽象方法,由子类实现
     * @param os 输出流
     */
    public abstract void out(OutputStream os);
 
    /**
     * 获取随机字符串
     * @return string
     */
    public String text()
    {
        return chars;
    }
}            
View Code

  3-2 >    附属类: Randoms.java

package com.test.Util;

import java.util.Random;

/**  

  * <p>随机工具类</p>  

  *  

  * @author: wuhongjun  

  * @version:1.0  

  */ 

 public class Randoms  

 {  

     private static final Random RANDOM = new Random();  

     //定义验证码字符.去除了O和I等容易混淆的字母  

    /* public static final char ALPHA[]={'A','B','C','D','E','F','G','H','G','K','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','q','r','s','t','u','v','w','x','y','z','2','3','4','5','6','7','8','9'};  */

     public static final char ALPHA[]={'1','2','3','4','5','6','7','8','9'};  

     /**  

      * 产生两个数之间的随机数  

      * @param min 小数  

      * @param max 比min大的数  

      * @return int 随机数字  

      */ 

     public static int num(int min, int max)  

     {  

         return min + RANDOM.nextInt(max - min);  

     }  

    

     /**  

      * 产生0--num的随机数,不包括num  

      * @param num 数字  

      * @return int 随机数字  

      */ 

     public static int num(int num)  

     {  

         return RANDOM.nextInt(num);  

     }  

    

     public static char alpha()  

     {  

         return ALPHA[num(0, ALPHA.length)];  

     }  

 } 
View Code

  3-3 >    附属类: SpecCaptcha.java

package com.test.Util;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;

import javax.imageio.ImageIO;

    /**
     * <p>png格式验证码</p>
     *
     * @author: wuhongjun
     * @version:1.0
     */
    public class SpecCaptcha extends Captcha
    {
        public SpecCaptcha()
        {
        }
        public SpecCaptcha(int width, int height)
        {
            this.width = width;
            this.height = height;
        }
        public SpecCaptcha(int width, int height, int len,char[] shu){
            this(width,height);
            this.len = len;
            this.shu=shu;
        }
        public SpecCaptcha(int width, int height, int len, Font font,char[] shu){
            this(width,height,len,shu);
            this.font = font;
        }
        /**
         * 生成验证码
         * @throws java.io.IOException IO异常
         */
        @Override
        public void out(OutputStream out){
            graphicsImage(this.shu, out);
        }
     
        /**
         * 画随机码图
         * @param strs 文本
         * @param out 输出流
         */
        private boolean graphicsImage(char[] strs, OutputStream out){
            boolean ok = false;
            try
            {
                BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
                Graphics2D g = (Graphics2D)bi.getGraphics();
                AlphaComposite ac3;
                Color color ;
                int len = strs.length;
                g.setColor(Color.WHITE);
                g.fillRect(0,0,width,height);
                // 随机画干扰的蛋蛋
                for(int i=0;i<15;i++){
                    color = color(150, 250);
                    g.setColor(color);
                    g.drawOval(Randoms.num(width), Randoms.num(height), 5+Randoms.num(10), 5+Randoms.num(10));// 画蛋蛋,有蛋的生活才精彩
                    color = null;
                }
                g.setFont(font);
                int h  = height - ((height - font.getSize()) >>1),
                    w = width/len,
                    size = w-font.getSize()+1;
                /* 画字符串 */
                for(int i=0;i<len;i++)
                {
                    ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f);// 指定透明度
                    g.setComposite(ac3);
                    color = new Color(20 + Randoms.num(110), 20 + Randoms.num(110), 20 + Randoms.num(110));// 对每个字符都用随机颜色
                    g.setColor(color);
                    g.drawString(strs[i]+"",(width-(len-i)*w)+size, h-4);
                    color = null;
                    ac3 = null;
                }
                ImageIO.write(bi, "png", out);
                out.flush();
                ok = true;
            }catch (IOException e){
                ok = false;
            }finally
            {
                Streams.close(out);
            }
            return ok;
        }
    }
View Code

  3-3 >    附属类: Streams.java

package com.test.Util;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

 public class Streams  

 {  

     /**  

      * 关闭输入流  

      * @param in 输入流  

      */ 

     public static void close(InputStream in) {  

         if (in != null) {  

            try {  

                 in.close();  

             } catch (IOException ioex) {  

                 // ignore  

             }  

         }  

     }  

    

     /**  

      * 关闭输出流  

      * @param out 输出流  

      */ 

     public static void close(OutputStream out) {  

         if (out != null) {  

             try {  

                 out.flush();  

             } catch (IOException ioex) {  

                 // ignore  

             }  

             try {  

                 out.close();  

             } catch (IOException ioex) {  

                 // ignore  

             }  

         }  

     }  

 } 
View Code

4.  点击登录按钮后   后台action 校验 验证码是否正确 (userDTO.getCheckCode()   获取前台页面传递过来的 用户输入的验证码)

public String login() {
        HttpSession session2 = ServletActionContext.getRequest().getSession();
        String checkCode = (String)session2.getAttribute(userDTO.getCheckCode());
        if(checkCode == null) {
            return "login";
        }else {
            return "welcome";
        }
    }
posted @ 2018-05-04 11:13  林**  阅读(2733)  评论(0编辑  收藏  举报