100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > SpringBoot+kaptcha生成验证码

SpringBoot+kaptcha生成验证码

时间:2018-10-28 11:29:44

相关推荐

SpringBoot+kaptcha生成验证码

SpringBoot+kaptcha生成验证码

1.在pom.xml文件中添加kaptcha引用

<!--验证码 --><dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId></dependency>

2.添加配置类CaptchaConfig

import java.util.Properties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import com.google.code.kaptcha.impl.DefaultKaptcha;import com.google.code.kaptcha.util.Config;import static com.google.code.kaptcha.Constants.*;@Configurationpublic class CaptchaConfig{/*** 生成字符验证码*/@Bean(name = "captchaProducer")public DefaultKaptcha getKaptchaBean(){DefaultKaptcha defaultKaptcha = new DefaultKaptcha();Properties properties = new Properties();// 是否有边框 默认为true 我们可以自己设置yes,noproperties.setProperty(KAPTCHA_BORDER, "yes");// 验证码文本字符颜色 默认为Color.BLACKproperties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");// 验证码图片宽度 默认为200properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");// 验证码图片高度 默认为50properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");// 验证码文本字符大小 默认为40properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");// KAPTCHA_SESSION_KEYproperties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");// 验证码文本字符长度 默认为5properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");// 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");// 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpyproperties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");Config config = new Config(properties);defaultKaptcha.setConfig(config);return defaultKaptcha;}/*** 生成算术验证码 自定义生成规则*/@Bean(name = "captchaProducerMath")public DefaultKaptcha getKaptchaBeanMath(){DefaultKaptcha defaultKaptcha = new DefaultKaptcha();Properties properties = new Properties();// 是否有边框 默认为true 我们可以自己设置yes,noproperties.setProperty(KAPTCHA_BORDER, "yes");// 边框颜色 默认为Color.BLACKproperties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90");// 验证码文本字符颜色 默认为Color.BLACKproperties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");// 验证码图片宽度 默认为200properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");// 验证码图片高度 默认为50properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");// 验证码文本字符大小 默认为40properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");// KAPTCHA_SESSION_KEYproperties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");// 验证码文本生成器 自定义验证码生成规则的类properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "包名.KaptchaTextCreator");// 验证码文本字符间距 默认为2properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3");// 验证码文本字符长度 默认为5properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");// 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");// 验证码噪点颜色 默认为Color.BLACKproperties.setProperty(KAPTCHA_NOISE_COLOR, "white");// 干扰实现类properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");// 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpyproperties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");Config config = new Config(properties);defaultKaptcha.setConfig(config);return defaultKaptcha;}}

3.添加验证码生成规则类 KaptchaTextCreator

import java.util.Random;import com.google.code.kaptcha.text.impl.DefaultTextCreator;/*** 验证码生成规则* 算术验证码*/public class KaptchaTextCreator extends DefaultTextCreator{private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");@Overridepublic String getText(){// 生成算术的两个值Random random = new Random();int x = random.nextInt(10);int y = random.nextInt(10);// 随机确定算术的符号(+ - * /)int randomoperands = (int) Math.round(Math.random() * 2);// 算术验证码StringBuilder suChinese = new StringBuilder();// 算术结果Integer result = 0;// 生成算术验证码 if (randomoperands == 0){result = x * y;suChinese.append(CNUMBERS[x]);suChinese.append("*");suChinese.append(CNUMBERS[y]);}else if (randomoperands == 1){if (!(x == 0) && y % x == 0){// 除数不能为o 并且算术必须能整除result = y / x;suChinese.append(CNUMBERS[y]);suChinese.append("/");suChinese.append(CNUMBERS[x]);}else{result = x + y;suChinese.append(CNUMBERS[x]);suChinese.append("+");suChinese.append(CNUMBERS[y]);}}else if (randomoperands == 2){if (x >= y){// 算术差不能为负数result = x - y;suChinese.append(CNUMBERS[x]);suChinese.append("-");suChinese.append(CNUMBERS[y]);}else{result = y - x;suChinese.append(CNUMBERS[y]);suChinese.append("-");suChinese.append(CNUMBERS[x]);}}else{result = x + y;suChinese.append(CNUMBERS[x]);suChinese.append("+");suChinese.append(CNUMBERS[y]);}// 将算术结果拼入生成的结果 中间加一个标识的特殊字符,一遍返回之前截取suChinese.append("=?@" + result);return suChinese.toString();}}

4.添加生成验证码图片工具类 Base64

(这一段是百度搜的 可以用,粘贴复制就好,如果已经有方法了用自己的也行,能用就好)

public final class Base64{static private final intBASELENGTH = 128;static private final intLOOKUPLENGTH = 64;static private final intTWENTYFOURBITGROUP = 24;static private final intEIGHTBIT = 8;static private final intSIXTEENBIT = 16;static private final intFOURBYTE = 4;static private final intSIGN = -128;static private final char PAD = '=';static final private byte[] base64Alphabet = new byte[BASELENGTH];static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];static{for (int i = 0; i < BASELENGTH; ++i){base64Alphabet[i] = -1;}for (int i = 'Z'; i >= 'A'; i--){base64Alphabet[i] = (byte) (i - 'A');}for (int i = 'z'; i >= 'a'; i--){base64Alphabet[i] = (byte) (i - 'a' + 26);}for (int i = '9'; i >= '0'; i--){base64Alphabet[i] = (byte) (i - '0' + 52);}base64Alphabet['+'] = 62;base64Alphabet['/'] = 63;for (int i = 0; i <= 25; i++) {lookUpBase64Alphabet[i] = (char) ('A' + i);}for (int i = 26, j = 0; i <= 51; i++, j++){lookUpBase64Alphabet[i] = (char) ('a' + j);}for (int i = 52, j = 0; i <= 61; i++, j++){lookUpBase64Alphabet[i] = (char) ('0' + j);}lookUpBase64Alphabet[62] = (char) '+';lookUpBase64Alphabet[63] = (char) '/';}private static boolean isWhiteSpace(char octect){return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);}private static boolean isPad(char octect){return (octect == PAD);}private static boolean isData(char octect) {return (octect < BASELENGTH && base64Alphabet[octect] != -1);}public static String encode(byte[] binaryData) {if (binaryData == null){return null;}int lengthDataBits = binaryData.length * EIGHTBIT;if (lengthDataBits == 0){return "";}int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;char encodedData[] = null;encodedData = new char[numberQuartet * 4];byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;int encodedIndex = 0;int dataIndex = 0;for (int i = 0; i < numberTriplets; i++){b1 = binaryData[dataIndex++];b2 = binaryData[dataIndex++];b3 = binaryData[dataIndex++];l = (byte) (b2 & 0x0f);k = (byte) (b1 & 0x03);byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];}if (fewerThan24bits == EIGHTBIT){b1 = binaryData[dataIndex];k = (byte) (b1 & 0x03);byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];encodedData[encodedIndex++] = PAD;encodedData[encodedIndex++] = PAD;}else if (fewerThan24bits == SIXTEENBIT){b1 = binaryData[dataIndex];b2 = binaryData[dataIndex + 1];l = (byte) (b2 & 0x0f);k = (byte) (b1 & 0x03);byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];encodedData[encodedIndex++] = PAD;}return new String(encodedData);}public static byte[] decode(String encoded){if (encoded == null){return null;}char[] base64Data = encoded.toCharArray();int len = removeWhiteSpace(base64Data);if (len % FOURBYTE != 0){return null;}int numberQuadruple = (len / FOURBYTE);if (numberQuadruple == 0) {return new byte[0];}byte decodedData[] = null;byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;char d1 = 0, d2 = 0, d3 = 0, d4 = 0;int i = 0;int encodedIndex = 0;int dataIndex = 0;decodedData = new byte[(numberQuadruple) * 3];for (; i < numberQuadruple - 1; i++){if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))|| !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++]))){return null;} b1 = base64Alphabet[d1];b2 = base64Alphabet[d2];b3 = base64Alphabet[d3];b4 = base64Alphabet[d4];decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);}if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {return null;}b1 = base64Alphabet[d1];b2 = base64Alphabet[d2];d3 = base64Data[dataIndex++];d4 = base64Data[dataIndex++];if (!isData((d3)) || !isData((d4))){if (isPad(d3) && isPad(d4)){if ((b2 & 0xf) != 0){return null;}byte[] tmp = new byte[i * 3 + 1];System.arraycopy(decodedData, 0, tmp, 0, i * 3);tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);return tmp;}else if (!isPad(d3) && isPad(d4)){b3 = base64Alphabet[d3];if ((b3 & 0x3) != 0){return null;}byte[] tmp = new byte[i * 3 + 2];System.arraycopy(decodedData, 0, tmp, 0, i * 3);tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));return tmp;}else{return null;}}else{b3 = base64Alphabet[d3];b4 = base64Alphabet[d4];decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);}return decodedData;}private static int removeWhiteSpace(char[] data){if (data == null){return 0;}int newSize = 0;int len = data.length;for (int i = 0; i < len; i++){if (!isWhiteSpace(data[i])){data[newSize++] = data[i];}}return newSize;}}

5.添加请求调用Service - ValidateCodeServiceImpl

import java.awt.image.BufferedImage;import java.io.IOException;import java.util.concurrent.TimeUnit;import javax.annotation.Resource;import javax.imageio.ImageIO;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.util.FastByteArrayOutputStream;import com.google.code.kaptcha.Producer;/*** 验证码实现处理*/@Servicepublic class ValidateCodeServiceImpl implements ValidateCodeService{@Resource(name = "captchaProducer")private Producer captchaProducer;@Resource(name = "captchaProducerMath")private Producer captchaProducerMath;// redis @Autowiredprivate RedisService redisService;/*** 生成验证码* AjaxResult 是返回给前端的对象,这里根据自己实际项目返回*/@Overridepublic AjaxResult createCapcha(captchaType) throws IOException, CaptchaException {// 保存验证码信息// 生成的uuid规则自己定义,能保证唯一就好String uuid = IdUtils.simpleUUID();// 验证码 redis keyString verifyKey = "captcha_codes:" + uuid;String capStr = null;String code = null;BufferedImage image = null;// 生成验证码 根据参数不同,选择不同的验证码if ("math".equals(captchaType)){// 算术验证码String capText = captchaProducerMath.createText();// 截取生成返回图片的内容capStr = capText.substring(0, capText.lastIndexOf("@"));// 截取要校验的结果code = capText.substring(capText.lastIndexOf("@") + 1);// 生成图片image = captchaProducerMath.createImage(capStr);}else if ("char".equals(captchaType)){// 字符验证码capStr = code = captchaProducer.createText();image = captchaProducer.createImage(capStr);}// verifyKey 缓存的键值, code 缓存的值, 5 时间, TimeUnit.MINUTES 分钟redisService.setCacheObject(verifyKey, code, 5, TimeUnit.MINUTES);// 转换流信息写出FastByteArrayOutputStream os = new FastByteArrayOutputStream();try{ImageIO.write(image, "jpg", os);}catch (IOException e){return AjaxResult.error(e.getMessage());}// 返回给前端的对象,这里根据自己实际项目返回AjaxResult ajax = AjaxResult.success();ajax.put("uuid", uuid);ajax.put("image", Base64.encode(os.toByteArray()));return ajax;}/*** 校验验证码* code 前端填写的验证码* uuid 和验证码一起生成的唯一标识*/@Overridepublic void checkCapcha(String code, String uuid) throws CaptchaException{if (StringUtils.isEmpty(code)){throw new CaptchaException("验证码不能为空");}if (StringUtils.isEmpty(uuid)){throw new CaptchaException("验证码已失效");}String verifyKey = "captcha_codes:" + uuid;// 从redis中取出uuid对应的验证码信息 String captcha = redisService.getCacheObject(verifyKey);// 将用过的验证码信息从redis中删除redisService.deleteObject(verifyKey);// 检验验证码 不区分大小写if (!code.equalsIgnoreCase(captcha)){throw new CaptchaException("验证码错误");}}}

6.生成效果

算术验证码:

字符验证码:

参考博文:

/qq_27948811/article/details/89404946

/p/1f2f7c47e812

/u/4847277/blog/4734550

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。