java图文验证码登录验证

<div class="tip verifyCode-box">
	<input class="verifyCode" name="verifyCode" type="text" id="verifyCode" maxlength="4" title="验证码" value="" nullmsg="请输入验证码!"  placeholder="请输入验证码"  />
	<img id="code" alt="verifyCode" src="/ntkoysb/loginAction.do?getVerifyCode" >
</div>
//刷新验证码,记得访问账号、密码、验证码错误需要刷新验证码
window.onload = function () {
    var img = document.getElementById("code");
    img.onclick = function() {
    	var date = new Date().getTime();
        img.src = "/a/login.do?getCode&time=" + date;
//我们刷新验证码需要重新请求服务器,我们路径不能是一模一样的,不然浏览器会一直加载本地已经缓存的图片,通过加一个时间后缀来欺骗服务器来达到我们的目的。
	}
}
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.servlet.http.HttpSession;

public class VerifyCodeUtil {
	/**
     * 照片存在session的key
     */
    public static final String SESSION_KEY = "verifyCode";

    public static final String BUFFIMG_KEY = "buffImg";
    /**
     * 验证码图片的宽度。
     */
    private static int width = 100;
    /**
     * 过期时长 一分钟
     */
    public static final long VERIFYCODE_TIMEOUT = 60*1000;
    /**
     *  验证码图片的高度。
     */
    private static int height = 30;
    /**
     * 验证码字符个数
     */
    private static int codeCount = 4;
    /**
     * 字体高度
     */
    private static int fontHeight;
    /**
     * 干扰线数量
     */
    private static int interLine = 12;
    /**
     * 第一个字符的x轴值,因为后面的字符坐标依次递增,所以它们的x轴值是codeX的倍数
     */
    private static int codeX;
    /**
     * codeY ,验证字符的y轴值,因为并行所以值一样
     */
    private static int codeY;
    /**
     * codeSequence 表示字符允许出现的序列值
     */
    static char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
            'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
            'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
    public static Map<String, Object> getVerifyCode(){
        Map<String, Object> result = new HashMap<>();
        //width-4 除去左右多余的位置,使验证码更加集中显示,减得越多越集中。
        //codeCount+1     //等比分配显示的宽度,包括左右两边的空格
        codeX = (width-4) / (codeCount+1);
        //height - 10 集中显示验证码
        fontHeight = height - 10;
        codeY = height - 7;
        // 定义图像buffer
        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D gd = buffImg.createGraphics();
        // 创建一个随机数生成器类
        Random random = new Random();
        // 将图像填充为白色
        gd.setColor(Color.WHITE);
        gd.fillRect(0, 0, width, height);
        // 创建字体,字体的大小应该根据图片的高度来定。
        Font font = new Font("Times New Roman", Font.PLAIN, fontHeight);
        // 设置字体。
        gd.setFont(font);
        // 画边框。
        gd.setColor(Color.BLACK);
        gd.drawRect(0, 0, width - 1, height - 1);
        // 随机产生16条干扰线,使图象中的认证码不易被其它程序探测到。
        gd.setColor(Color.gray);
        for (int i = 0; i < interLine; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            gd.drawLine(x, y, x + xl, y + yl);
        }
        // randomCode用于保存随机产生的验证码,以便用户登录后进行验证。
        StringBuffer randomCode = new StringBuffer();
        int red = 0, green = 0, blue = 0;
        // 随机产生codeCount数字的验证码。
        for (int i = 0; i < codeCount; i++) {
            // 得到随机产生的验证码数字。
            String strRand = String.valueOf(codeSequence[random.nextInt(36)]);
            // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。
            red = random.nextInt(255);
            green = random.nextInt(255);
            blue = random.nextInt(255);
            // 用随机产生的颜色将验证码绘制到图像中。
            gd.setColor(new Color(red,green,blue));
            gd.drawString(strRand, (i + 1) * codeX, codeY);
            // 将产生的四个随机数组合在一起。
            randomCode.append(strRand);
        }
        result.put(BUFFIMG_KEY, buffImg);
        result.put(SESSION_KEY, randomCode.toString());
        return result;
    }
    /**
     * 定时删除session中存在的验证码信息
     * @param session
     */
    public static void removeAttrbute(final HttpSession session) {
        final Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                session.removeAttribute(SESSION_KEY);
                timer.cancel();
            }
        }, VERIFYCODE_TIMEOUT);
    }
}
/**
     * 生成验证码
     * @param request
     * @param response
     */
    @RequestMapping(params = "getVerifyCode")
    public void getVerifyCode(HttpServletRequest request, HttpServletResponse response){
        Map<String, Object> map = VerifyCodeUtil.getVerifyCode();
        HttpSession session = request.getSession();
        session.setAttribute(VerifyCodeUtil.SESSION_KEY, map.get(VerifyCodeUtil.SESSION_KEY));
        // 禁止图像缓存。
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        // 将图像输出到Servlet输出流中。
        try {
            ServletOutputStream sos = response.getOutputStream();
            ImageIO.write((RenderedImage) map.get(VerifyCodeUtil.BUFFIMG_KEY), "jpeg", sos);
            sos.close();
            //设置验证码过期时间
            VerifyCodeUtil.removeAttrbute(session);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 验证验证码
     */
    @RequestMapping(params = "getVerifyCodeContent")
    public String getVerifyCodeContent(String inputVerifyCode){
        //获取当前线程绑定的request对象
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpSession session = request.getSession();
        String va = "";
        // 这个VerifyCodeFactory.SESSION_KEY是在servlet中存入session的名字
        String verifyCode = (String)session.getAttribute(VerifyCodeUtil.SESSION_KEY);
        if(null == verifyCode || verifyCode.isEmpty()){
            System.out.println("验证码过期请重新验证");
//            throw new DisabledException("验证码过期,请重新验证");
            va = "3";
            return va;
        }
        // 不分区大小写
        verifyCode = verifyCode.toLowerCase();
        inputVerifyCode = inputVerifyCode.toLowerCase();

//        log.info("验证码:{}, 用户输入:{}", verifyCode, inputVerifyCode);
        System.out.println(verifyCode+":"+inputVerifyCode);
        if (verifyCode.equals(inputVerifyCode)) {
        	va = "1";
		}else {
			va = "2";
		}
        return va;
    }

你可能感兴趣的:(Java,java,servlet,开发语言)