From 6726e7716e8d18b45b572f2a0489ecdfe613ffb6 Mon Sep 17 00:00:00 2001 From: yueye <768242801@qq.com> Date: Fri, 31 Dec 2021 11:29:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20=E4=BD=BF=E7=94=A8hutool?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E7=A0=81=E6=9B=BF=E6=8D=A2=E5=8E=9F=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/ruoyi-gateway-dev.yml | 10 +- .../core/utils/reflect/ReflectUtils.java | 63 +-------- ruoyi-gateway/pom.xml | 6 - .../captcha/UnsignedMathGenerator.java | 85 ++++++++++++ .../ruoyi/gateway/config/CaptchaConfig.java | 121 ++++++++---------- .../gateway/config/KaptchaTextCreator.java | 75 ----------- .../config/properties/CaptchaProperties.java | 25 +++- .../ruoyi/gateway/enums/CaptchaCategory.java | 35 +++++ .../com/ruoyi/gateway/enums/CaptchaType.java | 29 +++++ .../service/impl/ValidateCodeServiceImpl.java | 74 +++++------ 10 files changed, 268 insertions(+), 255 deletions(-) create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/captcha/UnsignedMathGenerator.java delete mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/KaptchaTextCreator.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/enums/CaptchaCategory.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/enums/CaptchaType.java diff --git a/config/ruoyi-gateway-dev.yml b/config/ruoyi-gateway-dev.yml index e39a893f..9920eab4 100644 --- a/config/ruoyi-gateway-dev.yml +++ b/config/ruoyi-gateway-dev.yml @@ -49,8 +49,16 @@ spring: security: # 验证码 captcha: + # 是否开启验证码 enabled: true - type: math + # 验证码类型 math 数组计算 char 字符验证 + type: MATH + # line 线段干扰 circle 圆圈干扰 shear 扭曲干扰 + category: CIRCLE + # 数字验证码位数 + numberLength: 1 + # 字符验证码长度 + charLength: 4 # 防止XSS攻击 xss: enabled: true diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/reflect/ReflectUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/reflect/ReflectUtils.java index 3d8382b2..30b18680 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/reflect/ReflectUtils.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/reflect/ReflectUtils.java @@ -1,19 +1,16 @@ package com.ruoyi.common.core.utils.reflect; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.Date; +import cn.hutool.core.util.ReflectUtil; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.core.utils.DateUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.apache.poi.ss.usermodel.DateUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.ruoyi.common.core.text.Convert; -import com.ruoyi.common.core.utils.DateUtils; + +import java.lang.reflect.*; +import java.util.Date; /** * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数. @@ -21,7 +18,7 @@ import com.ruoyi.common.core.utils.DateUtils; * @author ruoyi */ @SuppressWarnings("rawtypes") -public class ReflectUtils +public class ReflectUtils extends ReflectUtil { private static final String SETTER_PREFIX = "set"; @@ -70,52 +67,6 @@ public class ReflectUtils } } - /** - * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数. - */ - @SuppressWarnings("unchecked") - public static E getFieldValue(final Object obj, final String fieldName) - { - Field field = getAccessibleField(obj, fieldName); - if (field == null) - { - logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); - return null; - } - E result = null; - try - { - result = (E) field.get(obj); - } - catch (IllegalAccessException e) - { - logger.error("不可能抛出的异常{}", e.getMessage()); - } - return result; - } - - /** - * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数. - */ - public static void setFieldValue(final Object obj, final String fieldName, final E value) - { - Field field = getAccessibleField(obj, fieldName); - if (field == null) - { - // throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); - logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); - return; - } - try - { - field.set(obj, value); - } - catch (IllegalAccessException e) - { - logger.error("不可能抛出的异常: {}", e.getMessage()); - } - } - /** * 直接调用对象方法, 无视private/protected修饰符. * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用. diff --git a/ruoyi-gateway/pom.xml b/ruoyi-gateway/pom.xml index f32e37c5..9bc260fa 100644 --- a/ruoyi-gateway/pom.xml +++ b/ruoyi-gateway/pom.xml @@ -58,12 +58,6 @@ spring-boot-starter-actuator - - - com.github.penggle - kaptcha - - com.ruoyi diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/captcha/UnsignedMathGenerator.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/captcha/UnsignedMathGenerator.java new file mode 100644 index 00000000..772f9185 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/captcha/UnsignedMathGenerator.java @@ -0,0 +1,85 @@ +package com.ruoyi.gateway.captcha; + +import cn.hutool.captcha.generator.CodeGenerator; +import cn.hutool.core.math.Calculator; +import cn.hutool.core.util.CharUtil; +import cn.hutool.core.util.RandomUtil; +import com.ruoyi.common.core.utils.StringUtils; + +/** + * 无符号计算生成器 + * + * @author Lion Li + */ +public class UnsignedMathGenerator implements CodeGenerator { + + private static final long serialVersionUID = -5514819971774091076L; + + private static final String operators = "+-*"; + + /** + * 参与计算数字最大长度 + */ + private final int numberLength; + + /** + * 构造 + */ + public UnsignedMathGenerator() { + this(2); + } + + /** + * 构造 + * + * @param numberLength 参与计算最大数字位数 + */ + public UnsignedMathGenerator(int numberLength) { + this.numberLength = numberLength; + } + + @Override + public String generate() { + final int limit = getLimit(); + int min = RandomUtil.randomInt(limit); + int max = RandomUtil.randomInt(min, limit); + String number1 = Integer.toString(max); + String number2 = Integer.toString(min); + number1 = StringUtils.rightPad(number1, this.numberLength, CharUtil.SPACE); + number2 = StringUtils.rightPad(number2, this.numberLength, CharUtil.SPACE); + + return number1 + RandomUtil.randomChar(operators) + number2 + '='; + } + + @Override + public boolean verify(String code, String userInputCode) { + int result; + try { + result = Integer.parseInt(userInputCode); + } catch (NumberFormatException e) { + // 用户输入非数字 + return false; + } + + final int calculateResult = (int) Calculator.conversion(code); + return result == calculateResult; + } + + /** + * 获取验证码长度 + * + * @return 验证码长度 + */ + public int getLength() { + return this.numberLength * 2 + 2; + } + + /** + * 根据长度获取参与计算数字最大值 + * + * @return 最大值 + */ + private int getLimit() { + return Integer.parseInt("1" + StringUtils.repeat('0', this.numberLength)); + } +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/CaptchaConfig.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/CaptchaConfig.java index 963425e6..595e6b23 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/CaptchaConfig.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/CaptchaConfig.java @@ -1,83 +1,62 @@ package com.ruoyi.gateway.config; -import java.util.Properties; +import cn.hutool.captcha.CaptchaUtil; +import cn.hutool.captcha.CircleCaptcha; +import cn.hutool.captcha.LineCaptcha; +import cn.hutool.captcha.ShearCaptcha; 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.*; +import org.springframework.context.annotation.Lazy; + +import java.awt.*; /** * 验证码配置 - * - * @author ruoyi + * + * @author Lion Li */ @Configuration -public class CaptchaConfig -{ - @Bean(name = "captchaProducer") - public DefaultKaptcha getKaptchaBean() - { - DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); - Properties properties = new Properties(); - // 是否有边框 默认为true 我们可以自己设置yes,no - properties.setProperty(KAPTCHA_BORDER, "yes"); - // 验证码文本字符颜色 默认为Color.BLACK - properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); - // 验证码图片宽度 默认为200 - properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); - // 验证码图片高度 默认为50 - properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); - // 验证码文本字符大小 默认为40 - properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); - // KAPTCHA_SESSION_KEY - properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); - // 验证码文本字符长度 默认为5 - properties.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.ShadowGimpy - properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); - Config config = new Config(properties); - defaultKaptcha.setConfig(config); - return defaultKaptcha; +public class CaptchaConfig { + + private final int width = 160; + private final int height = 60; + private final Color background = Color.PINK; + private final Font font = new Font("Arial", Font.BOLD, 48); + + /** + * 圆圈干扰验证码 + */ + @Lazy + @Bean + public CircleCaptcha circleCaptcha() { + CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(width, height); + captcha.setBackground(background); + captcha.setFont(font); + return captcha; } - - @Bean(name = "captchaProducerMath") - public DefaultKaptcha getKaptchaBeanMath() - { - DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); - Properties properties = new Properties(); - // 是否有边框 默认为true 我们可以自己设置yes,no - properties.setProperty(KAPTCHA_BORDER, "yes"); - // 边框颜色 默认为Color.BLACK - properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90"); - // 验证码文本字符颜色 默认为Color.BLACK - properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue"); - // 验证码图片宽度 默认为200 - properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); - // 验证码图片高度 默认为50 - properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); - // 验证码文本字符大小 默认为40 - properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35"); - // KAPTCHA_SESSION_KEY - properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath"); - // 验证码文本生成器 - properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ruoyi.gateway.config.KaptchaTextCreator"); - // 验证码文本字符间距 默认为2 - properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3"); - // 验证码文本字符长度 默认为5 - properties.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.BLACK - properties.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.ShadowGimpy - properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); - Config config = new Config(properties); - defaultKaptcha.setConfig(config); - return defaultKaptcha; + + /** + * 线段干扰的验证码 + */ + @Lazy + @Bean + public LineCaptcha lineCaptcha() { + LineCaptcha captcha = CaptchaUtil.createLineCaptcha(width, height); + captcha.setBackground(background); + captcha.setFont(font); + return captcha; } + + /** + * 扭曲干扰验证码 + */ + @Lazy + @Bean + public ShearCaptcha shearCaptcha() { + ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(width, height); + captcha.setBackground(background); + captcha.setFont(font); + return captcha; + } + } \ No newline at end of file diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/KaptchaTextCreator.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/KaptchaTextCreator.java deleted file mode 100644 index 9ec31737..00000000 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/KaptchaTextCreator.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.ruoyi.gateway.config; - -import java.util.Random; -import com.google.code.kaptcha.text.impl.DefaultTextCreator; - -/** - * 验证码文本生成器 - * - * @author ruoyi - */ -public class KaptchaTextCreator extends DefaultTextCreator -{ - private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(","); - - @Override - public String getText() - { - Integer result = 0; - Random random = new Random(); - int x = random.nextInt(10); - int y = random.nextInt(10); - StringBuilder suChinese = new StringBuilder(); - int randomoperands = (int) Math.round(Math.random() * 2); - 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) - { - 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(); - } -} \ No newline at end of file diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CaptchaProperties.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CaptchaProperties.java index 300cad5d..fdbc933c 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CaptchaProperties.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CaptchaProperties.java @@ -1,5 +1,7 @@ package com.ruoyi.gateway.config.properties; +import com.ruoyi.gateway.enums.CaptchaCategory; +import com.ruoyi.gateway.enums.CaptchaType; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cloud.context.config.annotation.RefreshScope; @@ -17,13 +19,28 @@ import org.springframework.context.annotation.Configuration; public class CaptchaProperties { /** - * 验证码开关 + * 验证码类型 */ - private Boolean enabled; + private CaptchaType type; /** - * 验证码类型(math 数组计算 char 字符) + * 验证码类别 */ - private String type; + private CaptchaCategory category; + + /** + * 数字验证码位数 + */ + private Integer numberLength; + + /** + * 字符验证码长度 + */ + private Integer charLength; + + /** + * 验证码开关 + */ + private Boolean enabled; } diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/enums/CaptchaCategory.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/enums/CaptchaCategory.java new file mode 100644 index 00000000..c0f99257 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/enums/CaptchaCategory.java @@ -0,0 +1,35 @@ +package com.ruoyi.gateway.enums; + +import cn.hutool.captcha.AbstractCaptcha; +import cn.hutool.captcha.CircleCaptcha; +import cn.hutool.captcha.LineCaptcha; +import cn.hutool.captcha.ShearCaptcha; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 验证码类别 + * + * @author Lion Li + */ +@Getter +@AllArgsConstructor +public enum CaptchaCategory { + + /** + * 线段干扰 + */ + LINE(LineCaptcha.class), + + /** + * 圆圈干扰 + */ + CIRCLE(CircleCaptcha.class), + + /** + * 扭曲干扰 + */ + SHEAR(ShearCaptcha.class); + + private final Class clazz; +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/enums/CaptchaType.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/enums/CaptchaType.java new file mode 100644 index 00000000..e4461ab8 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/enums/CaptchaType.java @@ -0,0 +1,29 @@ +package com.ruoyi.gateway.enums; + +import cn.hutool.captcha.generator.CodeGenerator; +import cn.hutool.captcha.generator.RandomGenerator; +import com.ruoyi.gateway.captcha.UnsignedMathGenerator; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 验证码类型 + * + * @author Lion Li + */ +@Getter +@AllArgsConstructor +public enum CaptchaType { + + /** + * 数字 + */ + MATH(UnsignedMathGenerator.class), + + /** + * 字符 + */ + CHAR(RandomGenerator.class); + + private final Class clazz; +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java index f60d97a4..f0c1ba6c 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java @@ -1,22 +1,22 @@ package com.ruoyi.gateway.service.impl; -import com.google.code.kaptcha.Producer; +import cn.hutool.captcha.AbstractCaptcha; +import cn.hutool.captcha.generator.CodeGenerator; +import cn.hutool.core.convert.Convert; import com.ruoyi.common.core.constant.Constants; import com.ruoyi.common.core.exception.CaptchaException; import com.ruoyi.common.core.utils.IdUtils; +import com.ruoyi.common.core.utils.SpringUtils; import com.ruoyi.common.core.utils.StringUtils; -import com.ruoyi.common.core.utils.sign.Base64; +import com.ruoyi.common.core.utils.reflect.ReflectUtils; import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.redis.utils.RedisUtils; import com.ruoyi.gateway.config.properties.CaptchaProperties; +import com.ruoyi.gateway.enums.CaptchaType; import com.ruoyi.gateway.service.ValidateCodeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.util.FastByteArrayOutputStream; -import javax.annotation.Resource; -import javax.imageio.ImageIO; -import java.awt.image.BufferedImage; import java.io.IOException; import java.util.concurrent.TimeUnit; @@ -28,12 +28,6 @@ import java.util.concurrent.TimeUnit; @Service public class ValidateCodeServiceImpl implements ValidateCodeService { - @Resource(name = "captchaProducer") - private Producer captchaProducer; - - @Resource(name = "captchaProducerMath") - private Producer captchaProducerMath; - @Autowired private CaptchaProperties captchaProperties; @@ -54,42 +48,38 @@ public class ValidateCodeServiceImpl implements ValidateCodeService // 保存验证码信息 String uuid = IdUtils.simpleUUID(); String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; - - String capStr = null, code = null; - BufferedImage image = null; - - String captchaType = captchaProperties.getType(); // 生成验证码 - 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); - } - + CaptchaType captchaType = captchaProperties.getType(); + boolean isMath = CaptchaType.MATH == captchaType; + Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength(); + CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length); + AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz()); + captcha.setGenerator(codeGenerator); + captcha.createCode(); + String code = isMath ? getCodeResult(captcha.getCode()) : captcha.getCode(); RedisUtils.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); - // 转换流信息写出 - FastByteArrayOutputStream os = new FastByteArrayOutputStream(); - try - { - ImageIO.write(image, "jpg", os); - } - catch (IOException e) - { - return AjaxResult.error(e.getMessage()); - } - ajax.put("uuid", uuid); - ajax.put("img", Base64.encode(os.toByteArray())); + ajax.put("img", captcha.getImageBase64()); return ajax; } + private String getCodeResult(String capStr) { + int numberLength = captchaProperties.getNumberLength(); + int a = Convert.toInt(StringUtils.substring(capStr, 0, numberLength).trim()); + char operator = capStr.charAt(numberLength); + int b = Convert.toInt(StringUtils.substring(capStr, numberLength + 1, numberLength + 1 + numberLength).trim()); + switch (operator) { + case '*': + return Convert.toStr(a * b); + case '+': + return Convert.toStr(a + b); + case '-': + return Convert.toStr(a - b); + default: + return StringUtils.EMPTY; + } + } + /** * 校验验证码 */