SpringMVC 加入 Kaptcha 实现图片验证码

加入依赖
<!-- Kaptcha 验证码插件 -->
<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>
在 spring-mvc.xml 中加入
    <!-- Kaptcha 图片验证码 -->
    <bean id="chptchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha"> 
        <property name="config" >
            <bean class="com.google.code.kaptcha.util.Config">
                <constructor-arg>
                    <props>
                        <prop key="kaptcha.border">yes</prop>
                        <prop key="kaptcha.border.color">105,179,90</prop>
                        <prop key="kaptcha.textproducer.font.color">blue</prop>
                        <prop key="kaptcha.image.width">125</prop>
                        <prop key="kaptcha.image.height">45</prop>
                        <prop key="kaptcha.textproducer.font.size">45</prop>
                        <prop key="kaptcha.session.key">code</prop>
                        <!-- 
                        <prop key="kaptcha.textproducer.char.string">abcdfkgujtmei123456789</prop>
                         -->
                        <prop key="kaptcha.textproducer.char.length">4</prop>
                        <prop key="kaptcha.textproducer.font.names">宋体,楷体,微软雅黑</prop>
                    </props>
                </constructor-arg>
            </bean>     
        </property>
    </bean>

属性具体配置:http://www.jianshu.com/p/e6c71bc37759


文本实现类:kaptcha.textproducer.impl 值为:com.google.code.kaptcha.text.impl.DefaultTextCreator

验证码值配置:kaptcha.textproducer.char.string 值:abcde2345678gfynmnpwx(随意你自己写)

验证码的长度:kaptcha.textproducer.char.length 值:

字体:kaptcha.textproducer.font.names 值:Arial,Courier

字体颜色:kaptcha.textproducer.font.color 值: r,g,b 或者 white,black,blue

文字间隔:kaptcha.textproducer.char.space 值:

干扰实现类:kaptcha.noise.impl 值:com.google.code.kaptcha.impl.DefaultNoise/NoNoise

干扰颜色:kaptcha.noise.color 值: r,g,b 或者 white,black,blue

图片样式:kaptcha.obscurificator.impl 值:

水纹com.google.code.kaptcha.impl.WaterRipple

鱼眼com.google.code.kaptcha.impl.FishEyeGimpy

阴影com.google.code.kaptcha.impl.ShadowGimpy

背景实现类:kaptcha.background.impl 值:com.google.code.kaptcha.impl.DefaultBackground

背景渐变色开始:kaptcha.background.clear.from 值:r,g,b 或者 white,black,blue

背景渐变色结束:kaptcha.background.clear.to 值:r,g,b 或者 white,black,blue

文字渲染器:kaptcha.word.impl 值:com.google.code.kaptcha.text.impl.DefaultWordRenderer

session中存放验证码的key键:kaptcha.session.key 值:KAPTCHA_SESSION_KEY

Contro;;er 中实现
/**
     * 验证码生成
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @RequestMapping(value="/captcha-image")
    public ModelAndView getKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
        
        System.out.println(request);
        System.out.println(response);
        // 从 session 获取验证码的 code 值
        HttpSession session = request.getSession();
        System.out.println(session);
        String code = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        System.out.println(code);
        
        // 设置清除浏览器的缓存
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/png");
        
        // 设置 session 
        String capText = captchaProducer.createText();
        System.out.println("设置session:" + capText);
        session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);
        
        // 输出验证码
        BufferedImage bi = captchaProducer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(bi, "png", out);
        out.flush();
        out.close();
        
        return null;
    }

    /**
     * 验证码校验
     * @param request
     * @param response
     * @param code_j
     * @return
     * @throws Exception
     */
    @RequestMapping("/codeCheck")
    public String codeCheck(HttpServletRequest request, HttpServletResponse response,
            @RequestParam("code")String code_j) throws Exception {
        
        HttpSession session = request.getSession();
        String code = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        JSONObject json = new JSONObject();
        if (code_j.equals(code)) {
            json.put("ok", true);
        } else {
            json.put("ok", false);
        }
        ResponseUtil.write(response, json);
        return null;
    }
JSP 页面
<tr>
    <td>验证码:</td>
    <td><input id="j_code" type="text" name="j_code" onblur="javascript:codeCheck()"></td>
    ![](${path }/test/captcha-image)
    <a href="javascript:chageCode()">看不清?换一张</a>
</tr>

    <script type="text/javascript">
        
        // 刷新验证码
        function chageCode() {
            var time = new Date().getTime();
            $("#kaptchaImage").attr('src', '${path }/test/captcha-image?id='+time);
        }

              // Ajax 验证验证码
        function codeCheck() {
            var code = $('#inputImagecode').val();
            $.post(
                '${path}/codeCheck',
                {
                    'code' : code
                },
                function(result) {
                    if(result.ok) {
                        //alert("验证码正确!");
                        $('#inputImagecode').css('background-color', 'rgba(91, 255, 173, 0.2)')
                        $('#submitbtn').addAttr('onsubmit');
                    } else {
                        //alert("验证码错误!");
                        $('#inputImagecode').css('background-color', 'rgba(255, 81, 81, 0.2)')
                        $('#submitbtn').removeAttr('onsubmit');
                    }
                }, 'json');
        }

    </script>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • 验证码定义:验证码是一种区分用户是计算机还是人的公共自动程序。作用:可以防止恶意破解密码,刷票、论坛灌水,有效防止...
    年少懵懂丶流年梦阅读 771评论 0 1
  • 几次闲谈发现,即使世界复杂多变、困难重重,仍然有人如鱼得水、游刃有余,取得令人艳羡的成就。这些人都是“有心人”:时...
    阳光玉豆阅读 506评论 0 2
  • 在家乡的夏末,我拖着硕大笨拙的行李箱来到北方,落地便已入秋。 适应新生活,心总也飘忽不定。北方出了名的干燥让我...
    大脸象阅读 474评论 11 1
  • 在互联网潮流下,一个新的用户需求就会拉动软件系统的更新换代和变革,不更新换代的软件在群控市场是没有竞争力的。兔客服...
    xiaoyi166阅读 213评论 0 0
  • 司徒来到距离前厅最远的后花园,才敢开口问话,因为他知道巫月的听力非同一般。 侍从悄声回复,刚才在去穹宫送饭的路...
    夷夏传说阅读 284评论 0 2