springmvc引入验证码kaptcha的使用方法

注意的一些点。

1.引入kaptcha的maven配置 引入验证码包

2.修改web.xml的过滤器filter(为了让验证码控制器不拦截)
3.修改src的返回属性返回base64(理由是让验证码的显示要调用ajax返回,ajax的返回类型dataType只有xml,html,script,json,jsonp,text,没有 resp.setContentType("image/jpeg“)图片类型,所以要用ajax读取图片,只能用base64位返回数据)
4.读取配置文件来设置验证码是否要用
5.生成验证码和token来跟前台当前用户确定,如果不用token无法却该验证码是哪个用户发送过来的

6.生成token放到redis里面之前确认是否还有token,如果该token已经生成就不再使用,重新生成

(1).pom.xml文件引用,这里没有引用原版google的,因为仓库里面没有

	        <dependency>
		    <groupId>com.github.penggle</groupId>
			    <artifactId>kaptcha</artifactId>
			    <version>2.3.2</version>
		</dependency>

(2).定义生成验证码

	<!-- google kaptcha的相关配置-->
    <bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">  
        <property name="config">  
            <bean class="com.google.code.kaptcha.util.Config">  
                <constructor-arg>  
                    <props> 
                        <!-- 是否有边框 可选yes 或者 no --> 
                        <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.textproducer.font.size">45</prop>  
                        <!-- 验证码图片的宽度 默认200 -->
                        <prop key="kaptcha.image.width">125</prop>  
                        <!-- 验证码图片的高度 默认50 -->
                        <prop key="kaptcha.image.height">50</prop>  
                        <!-- 验证码文本字符长度  默认为5 -->
                        <prop key="kaptcha.textproducer.char.length">4</prop>  
                        <!-- 验证码文本字体样式  默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)  -->
                        <prop key="kaptcha.textproducer.font.names">宋体,楷体,微软雅黑</prop>  
                    </props>  
                </constructor-arg>  
            </bean>  
        </property>  
    </bean>

(3).编写springmvc的controller   (ResponseBody是为了返回数据能直接给ajax用)

package com.csair.fwms.airlog.controller.sub;


import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;

import sun.misc.BASE64Encoder;

@Controller
@RequestMapping("captcha")
public class CaptchaController {

    @Resource
    private Producer captchaProducer;
    
    
	@Autowired
	private RedisTemplate<String, String> redisTemplate;
    /**
     *             
     *                获取验证码图片
     * @author         ccg
     * @param         request
     * @param         response
     * @return
     * @throws         IOException
     * Created        2017年1月17日 下午5:07:28
     */
    @RequestMapping("getCaptchaCode")
    @ResponseBody
    public Object getCaptchaCode(HttpServletRequest request, HttpServletResponse response) throws IOException{
      
        //生成验证码文本
        String capText = captchaProducer.createText();  
        System.out.println("生成验证码文本===="+capText);
        //利用生成的字符串构建图片
        BufferedImage bi = captchaProducer.createImage(capText);
        ByteArrayOutputStream  out = new ByteArrayOutputStream();  
        ImageIO.write(bi, "jpg", out);  
        BASE64Encoder  encoder = new BASE64Encoder();
        String base64Img = encoder.encode(out.toByteArray());
        
        response.setContentType("application/json");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setCharacterEncoding("UTF-8");
        
		String context = request.getContextPath();
        String token = RandomStringUtils.randomAlphanumeric(20);
 
        while (!StringUtils.isEmpty(redisTemplate.opsForValue().get(token))) {//redis里面如果有这个token就继续生成新的token,要生成一个没用过的token
        	System.out.println("----------------------");
        	System.out.println("新的token");
        	token = RandomStringUtils.randomAlphanumeric(20);
		}
        
		redisTemplate.opsForValue().set(token, capText);//token和验证码对应的放到redis里面
		Cookie vtokenCookie = new Cookie("vtoken", token);//把token放入到页面里去
		vtokenCookie.setMaxAge(60 * 30);
		vtokenCookie.setPath(context);
		response.addCookie(vtokenCookie);
        
        return base64Img;
    }
 
}

(4).获取配置文件属性

package com.csair.fwms.airlog.basic.util;

import java.io.IOException;

 

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;

import org.springframework.core.io.support.PropertiesLoaderUtils;

/**
 * 
 * @ClassName: TestProperties   
 * @Description: 获取配置文件信息  
 * @date: 2017年11月25日 上午10:56:00  
 * @version: 1.0.0
 */
public class PropertiesUtil{
    
     
	public static String getValue(String key){
		
	    Properties properties = new Properties();
	     // 使用InPutStream流读取properties文件
	     BufferedReader bufferedReader;

	     try {
   	    bufferedReader = new BufferedReader(new FileReader("src/main/resources/web.properties"));
			properties.load(bufferedReader);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	     // 获取key对应的value值
	    String keys= properties.getProperty(key);
		return keys;
		
	}
    
}


(5).页面和登陆的时候验证

		
		String vcode =PropertiesUtil.getValue("verificationCode");
		if(vcode.equals("1")||vcode=="1"){//是否开启验证码
                 if (StringUtils.isEmpty(loginParam.getVtoken())) {//验证码过期
				throw new ServiceException("验证码错误!");
                    }
			String code = redisTemplate.opsForValue().get(loginParam.getVtoken());
			if (!code.equals(loginParam.getCaptcha())) {//验证码是否正确
				throw new ServiceException("验证码错误!");
			}
		}
			

(6).登陆页面

            $.ajax({
                type: "post",
                contentType: "application/json; charset=utf-8",
                dataType: "text",
                url: "../captcha/getCaptchaCode",
                success: function(data) {
            		$("#imgCaptcha").attr('src', "data:image/jpeg;base64,"+data); 
                },
                error: function(e) {
                    console.log(e);
                }
            });
jQuery('#loginBtn').click(function() {
            	
        		var vtoken = $.cookie('vtoken'); 
    			
            	 var post = {
                         account: form['account'].value,
                         password: form['password'].value,
                         captcha: form['captcha'].value,
                         vtoken: vtoken
                 };
                $.ajax({
                    type: "post",
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    url: "../webapi/auth/login",
                    data: JSON.stringify(post),
                    success: function(data) {
                        if (!data.success) {
                            alert(data.exceptionMessage);
                            return;
                        }


                        window.location = '../webapi/home/index'
                    },
                    error: function(e) {
                        console.log(e);
                    }
                });
            });
            // $('body').delegate('[name="loginBtn"]', 'click', function() {


            // });
        });
            
           验证码文本框<img src="" width="112" height="42" id="imgCaptcha"  style="margin-bottom: -3px"/>   
              登陆失败后要刷新页面
$.ajax({
                    type: "post",
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    url: "../webapi/auth/login",
                    data: JSON.stringify(post),
                    success: function(data) {
                        if (!data.success) {
                            alert(data.exceptionMessage);
                            $.ajax({
                                type: "post",
                                contentType: "application/json; charset=utf-8",
                                dataType: "text",
                                url: "../captcha/getCaptchaCode",
                                success: function(data) {
                            		$("#imgCaptcha").attr('src', "data:image/jpeg;base64,"+data); 
                                },
                                error: function(e) {
                                    console.log(e);
                                }
                            });
                            return;
                        }

                        window.location = '../webapi/home/index'
                    },
                    error: function(e) {
                        console.log(e);
                    }
                });


}

猜你喜欢

转载自blog.csdn.net/bigwatermel/article/details/81032032