码迷,mamicode.com
首页 > 其他好文 > 详细

验证码

时间:2017-10-27 21:34:30      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:ref   获得   graphic   otn   oom   must   text   geo   nts   

   /**
     * 生成图形验证码
     */
    @RequestMapping("captcha.jpg")
    public void captcha(HttpServletRequest request, HttpServletResponse response) {
        dreamCaptcha.generate(request, response);
    }
/**
  *  验证码验证
  */
dreamCaptcha.validate(request, response, auth)
package com.ssy.test.utils;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.QuadCurve2D;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

/**
 * 生成验证码
 * @author ForeignStudent
 */
public class CaptchaUtils {
    // 默认的验证码大小
    private static final int WIDTH = 108, HEIGHT = 40, CODE_SIZE = 4;
    // 验证码随机字符数组
    protected static final char[] charArray = "3456789ABCDEFGHJKMNPQRSTUVWXY".toCharArray();
    // 验证码字体
    private static final Font[] RANDOM_FONT = new Font[] { new Font("nyala", Font.BOLD, 38),
            new Font("Arial", Font.BOLD, 32), new Font("Bell MT", Font.BOLD, 32),
            new Font("Credit valley", Font.BOLD, 34), new Font("Impact", Font.BOLD, 32),
            new Font(Font.MONOSPACED, Font.BOLD, 40) };

    /**
     * 生成验证码
     */
    static void generate(HttpServletResponse response, String vCode) {

        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");

        ServletOutputStream sos = null;
        try {
            drawGraphic(image, vCode);
            sos = response.getOutputStream();
            ImageIO.write(image, "JPEG", sos);
            sos.flush();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            IOUtils.closeQuietly(sos);
        }
    }

    // 生成随机类
    private static final Random RANDOM = new Random();

    /**
     * 生成验证码字符串
     * 
     * @return 验证码字符串
     */
    static String generateCode() {
        int count = CODE_SIZE;
        char[] buffer = new char[count];
        for (int i = 0; i < count; i++) {
            buffer[i] = charArray[RANDOM.nextInt(charArray.length)];
        }
        return new String(buffer);
    }

    private static void drawGraphic(BufferedImage image, String code) {
        // 获取图形上下文
        Graphics2D g = image.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
        // 图形抗锯齿
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 字体抗锯齿
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        // 设定背景色,淡色
        g.setColor(getRandColor(210, 250));
        g.fillRect(0, 0, WIDTH, HEIGHT);

        // 画小字符背景
        Color color = null;
        for (int i = 0; i < 20; i++) {
            color = getRandColor(120, 200);
            g.setColor(color);
            String rand = String.valueOf(charArray[RANDOM.nextInt(charArray.length)]);
            g.drawString(rand, RANDOM.nextInt(WIDTH), RANDOM.nextInt(HEIGHT));
            color = null;
        }
        // 取随机产生的认证码(4位数字)
        char[] buffer = code.toCharArray();
        for (int i = 0; i < buffer.length; i++) {
            char _code = buffer[i];
            // 旋转度数 最好小于45度
            int degree = RANDOM.nextInt(28);
            if (i % 2 == 0) {
                degree = degree * (-1);
            }
            // 定义坐标
            int x = 22 * i, y = 21;
            // 旋转区域
            g.rotate(Math.toRadians(degree), x, y);
            // 设定字体颜色
            color = getRandColor(20, 130);
            g.setColor(color);
            // 设定字体,每次随机
            g.setFont(RANDOM_FONT[RANDOM.nextInt(RANDOM_FONT.length)]);
            // 将认证码显示到图象中
            g.drawString("" + _code, x + 8, y + 10);
            // 旋转之后,必须旋转回来
            g.rotate(-Math.toRadians(degree), x, y);
        }
        // 图片中间曲线,使用上面缓存的color
        g.setColor(color);
        // width是线宽,float型
        BasicStroke bs = new BasicStroke(3);
        g.setStroke(bs);
        // 画出曲线
        QuadCurve2D.Double curve = new QuadCurve2D.Double(0d, RANDOM.nextInt(HEIGHT - 8) + 4, WIDTH / 2, HEIGHT / 2,
                WIDTH, RANDOM.nextInt(HEIGHT - 8) + 4);
        g.draw(curve);
        // 销毁图像
        g.dispose();
    }

    /**
     * 给定范围获得随机颜色
     */
    private static Color getRandColor(int fc, int bc) {
        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);
    }
}
package com.conferencerooms.utils.verifycode;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;

import com.conferencerooms.utils.StringUtils;

/**
 * 验证码验证
 * @author ForeignStudent
 */
public class DreamCaptcha implements InitializingBean {

    private final static Logger logger = LogManager.getLogger(DreamCaptcha.class);

    private static final String DEFAULT_COOKIE_NAME = "dream-captcha";
    private final static String DEFAULT_CHACHE_NAME = "dreamCaptchaCache";

    private final static int DEFAULT_MAX_AGE = -1; // cookie超时默认为session会话状态

    private CacheManager cacheManager;

    private String cacheName;
    private String cookieName;

    private Cache<String, String> dreamCaptchaCache;

    public DreamCaptcha() {
        this.cacheName = DEFAULT_CHACHE_NAME;
        this.cookieName = DEFAULT_COOKIE_NAME;
    }

    public DreamCaptcha(CacheManager cacheManager) {
        this();
        this.cacheManager = cacheManager;
    }

    public CacheManager getCacheManager() {
        return cacheManager;
    }

    public void setCacheManager(CacheManager cacheManager) {
        this.cacheManager = cacheManager;
    }

    public String getCacheName() {
        return cacheName;
    }

    public void setCacheName(String cacheName) {
        this.cacheName = cacheName;
    }

    public String getCookieName() {
        return cookieName;
    }

    public void setCookieName(String cookieName) {
        this.cookieName = cookieName;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(cacheManager, "cacheManager must not be null!");
        Assert.hasText(cacheName, "cacheName must not be empty!");
        Assert.hasText(cookieName, "cookieName must not be empty!");
        this.dreamCaptchaCache = cacheManager.getCache(cacheName);
    }

    /**
     * 生成验证码
     */
    public void generate(HttpServletRequest request, HttpServletResponse response) {
        // 先检查cookie的uuid是否存在
        String cookieValue = getCookieValue(request, cookieName);
        boolean hasCookie = true;
        if (StringUtils.isBlank(cookieValue)) {
            hasCookie = false;
            cookieValue = StringUtils.getUUId();
        }
        // 转成大写重要
        String captchaCode = CaptchaUtils.generateCode().toUpperCase();
        // 不存在cookie时设置cookie
        if (!hasCookie) {
            setCookie(response, cookieName, cookieValue, DEFAULT_MAX_AGE);
        }
        // 生成验证码
        CaptchaUtils.generate(response, captchaCode);
        dreamCaptchaCache.put(cookieValue, captchaCode);
    }

    /**
     * 仅能验证一次,验证后立即删除
     * 
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     * @param userInputCaptcha 用户输入的验证码
     * @return 验证通过返回 true, 否则返回 false
     */
    public boolean validate(HttpServletRequest request, HttpServletResponse response, String userInputCaptcha) {
        if (logger.isDebugEnabled()) {
            logger.debug("validate captcha userInputCaptcha is " + userInputCaptcha);
        }
        String cookieValue = getCookieValue(request, cookieName);
        if (StringUtils.isBlank(cookieValue)) {
            return false;
        }
        String captchaCode = dreamCaptchaCache.get(cookieValue);
        if (StringUtils.isBlank(captchaCode)) {
            return false;
        }
        // 转成大写重要
        userInputCaptcha = userInputCaptcha.toUpperCase();
        boolean result = userInputCaptcha.equals(captchaCode);
        if (result) {
            dreamCaptchaCache.remove(cookieValue);
            removeCookie(response, cookieName);
        }
        return result;
    }

    /**
     * 读取cookie
     * 
     * @param request
     * @param key
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String name) {
        Cookie cookie = org.springframework.web.util.WebUtils.getCookie(request, name);
        return cookie != null ? cookie.getValue() : null;
    }

    /**
     * 设置cookie
     * 
     * @param response
     * @param name
     * @param value
     * @param maxAgeInSeconds
     */
    public static void setCookie(HttpServletResponse response, String name, String value, int maxAgeInSeconds) {
        Cookie cookie = new Cookie(name, value);
        cookie.setPath("/");
        cookie.setMaxAge(maxAgeInSeconds);
        cookie.setHttpOnly(true);
        response.addCookie(cookie);
    }

    /**
     * 清除 某个指定的cookie
     * 
     * @param response
     * @param key
     */
    public static void removeCookie(HttpServletResponse response, String key) {
        setCookie(response, key, null, 0);
    }

    /**
     * 判断是否ajax请求 spring ajax 返回含有 ResponseBody 或者 RestController注解
     * 
     * @param handlerMethod HandlerMethod
     * @return 是否ajax请求
     */
    public static boolean isAjax(HandlerMethod handlerMethod) {
        ResponseBody responseBody = handlerMethod.getMethodAnnotation(ResponseBody.class);
        if (null != responseBody) {
            return true;
        }
        RestController restAnnotation = handlerMethod.getBeanType().getAnnotation(RestController.class);
        if (null != restAnnotation) {
            return true;
        }
        return false;
    }
}
    <!-- 验证码 -->
    <bean class="com.conferencerooms.utils.verifycode.DreamCaptcha">
        <property name="cacheManager" ref="shiroCacheManager"/>
        <property name="cacheName" value="halfHour"/>
    </bean>

验证码

标签:ref   获得   graphic   otn   oom   must   text   geo   nts   

原文地址:http://www.cnblogs.com/foreign-student/p/7745153.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!