diff --git a/tianai-captcha/src/main/java/cloud/tianai/captcha/common/AnyMap.java b/tianai-captcha/src/main/java/cloud/tianai/captcha/common/AnyMap.java index fe03829..ed4d3d6 100644 --- a/tianai-captcha/src/main/java/cloud/tianai/captcha/common/AnyMap.java +++ b/tianai-captcha/src/main/java/cloud/tianai/captcha/common/AnyMap.java @@ -13,7 +13,7 @@ import java.util.function.Function; @EqualsAndHashCode public class AnyMap implements Map { - private Map target; + private final Map target; public AnyMap() { target = new LinkedHashMap<>(); @@ -77,6 +77,39 @@ public class AnyMap implements Map { return new AnyMap(map); } + + public void addParam(String key, Object value) { + put(key, value); + } + + public Object getParam(String key) { + return get(key); + } + + public Object removeParam(String key) { + return remove(key); + } + + public Object removeParam(ParamKey paramKey) { + return removeParam(paramKey.getKey()); + } + + public void addParam(ParamKey paramKey, T value) { + addParam(paramKey.getKey(), value); + } + + public T getParam(ParamKey paramKey) { + return getParam(paramKey, null); + } + + public T getParam(ParamKey paramKey, T defaultValue) { + return (T) getParam(paramKey.getKey()); + + } + + public T getOrDefault(ParamKey paramKey, T defaultValue) { + return (T) getOrDefault(paramKey.getKey(), defaultValue); + } // ================== implement Map ======================= diff --git a/tianai-captcha/src/main/java/cloud/tianai/captcha/common/ParamKey.java b/tianai-captcha/src/main/java/cloud/tianai/captcha/common/ParamKey.java new file mode 100644 index 0000000..0c9bef5 --- /dev/null +++ b/tianai-captcha/src/main/java/cloud/tianai/captcha/common/ParamKey.java @@ -0,0 +1,12 @@ +package cloud.tianai.captcha.common; + +/** + * @Author: 天爱有情 + * @date 2024/11/20 11:34 + * @Description 此接口的作用是在给 {@link AnyMap} 添加/获取参数时做一个类型限制和转换 + */ +public interface ParamKey { + + String getKey(); + +} diff --git a/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/AbstractImageCaptchaGenerator.java b/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/AbstractImageCaptchaGenerator.java index 292351e..3aca2fb 100644 --- a/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/AbstractImageCaptchaGenerator.java +++ b/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/AbstractImageCaptchaGenerator.java @@ -2,10 +2,7 @@ package cloud.tianai.captcha.generator; import cloud.tianai.captcha.common.exception.ImageCaptchaException; import cloud.tianai.captcha.common.util.CollectionUtils; -import cloud.tianai.captcha.generator.common.model.dto.CaptchaExchange; -import cloud.tianai.captcha.generator.common.model.dto.CustomData; -import cloud.tianai.captcha.generator.common.model.dto.GenerateParam; -import cloud.tianai.captcha.generator.common.model.dto.ImageCaptchaInfo; +import cloud.tianai.captcha.generator.common.model.dto.*; import cloud.tianai.captcha.generator.common.util.CaptchaImageUtils; import cloud.tianai.captcha.generator.impl.transform.Base64ImageTransform; import cloud.tianai.captcha.interceptor.CaptchaInterceptor; @@ -136,6 +133,11 @@ public abstract class AbstractImageCaptchaGenerator implements ImageCaptchaGener public ImageCaptchaInfo wrapImageCaptchaInfo(CaptchaExchange captchaExchange) { ImageCaptchaInfo imageCaptchaInfo = doWrapImageCaptchaInfo(captchaExchange); imageCaptchaInfo.setData(captchaExchange.getCustomData()); + // 设置自定义容错值 + Number tolerant = captchaExchange.getParam().getParam(ParamKeyEnum.TOLERANT); + if (tolerant != null) { + imageCaptchaInfo.setTolerant(tolerant.floatValue()); + } return imageCaptchaInfo; } diff --git a/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/common/model/dto/GenerateParam.java b/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/common/model/dto/GenerateParam.java index b66a8fe..c88bae9 100644 --- a/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/common/model/dto/GenerateParam.java +++ b/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/common/model/dto/GenerateParam.java @@ -1,6 +1,7 @@ package cloud.tianai.captcha.generator.common.model.dto; import cloud.tianai.captcha.common.AnyMap; +import cloud.tianai.captcha.common.ParamKey; import cloud.tianai.captcha.common.constant.CaptchaTypeConstant; import lombok.Data; import lombok.EqualsAndHashCode; @@ -11,89 +12,93 @@ import lombok.EqualsAndHashCode; * @Description 生成参数 */ @Data -// param作为扩展字段暂时将param从equals和toString中移除掉 以适应 CacheImageCaptchaGenerator -@EqualsAndHashCode(exclude = "param") -public class GenerateParam { +@EqualsAndHashCode(callSuper = true) +public class GenerateParam extends AnyMap { + + public GenerateParam() { + // 设置一些默认值 + setBackgroundFormatName("jpeg"); + setTemplateFormatName("png"); + setObfuscate(false); + setType(CaptchaTypeConstant.SLIDER); + } /** * 背景格式化类型. */ - private String backgroundFormatName = "jpeg"; + private static final ParamKey backgroundFormatName = () -> "backgroundFormatName"; /** * 模板图片格式化类型. */ - private String templateFormatName = "png"; + private static final ParamKey templateFormatName = () -> "templateFormatName"; /** * 是否混淆. */ - private Boolean obfuscate = false; + private static final ParamKey obfuscate = () -> "obfuscate"; /** * 类型. */ - private String type = CaptchaTypeConstant.SLIDER; + private static final ParamKey type = () -> "type"; /** * 背景图片标签, 用户二级过滤背景图片,或指定某背景图片. */ - private String backgroundImageTag; + private static final ParamKey backgroundImageTag = () -> "backgroundImageTag"; /** * 滑动图片标签,用户二级过滤模板图片,或指定某模板图片.. */ - private String templateImageTag; - /** - * 扩展参数. - */ - private AnyMap param = new AnyMap(); + private static final ParamKey templateImageTag = () -> "templateImageTag"; - public void addParam(String key, Object value) { - doGetOrCreateParam().put(key, value); + + // =============== getter and setter ==================== + public void setBackgroundFormatName(String backgroundFormatName) { + addParam(GenerateParam.backgroundFormatName, backgroundFormatName); } - public Object getParam(String key) { - return param == null ? null : param.get(key); + public void setTemplateFormatName(String templateFormatName) { + addParam(GenerateParam.templateFormatName, templateFormatName); } - private AnyMap doGetOrCreateParam() { - if (param == null) { - param = new AnyMap(); - } - return param; + public void setObfuscate(boolean obfuscate) { + addParam(GenerateParam.obfuscate, obfuscate); } - public Object removeParam(String key) { - if (param == null) { - return null; - } - return param.remove(key); - } - public Object removeParam(ParamKey paramKey) { - return removeParam(paramKey.getKey()); + public void setType(String type) { + addParam(GenerateParam.type, type); } - public Object getOrDefault(String key, Object defaultValue) { - if (param == null) { - return defaultValue; - } - return param.getOrDefault(key, defaultValue); + public void setBackgroundImageTag(String backgroundImageTag) { + addParam(GenerateParam.backgroundImageTag, backgroundImageTag); } - - public Object putIfAbsent(String key, Object value) { - return doGetOrCreateParam().putIfAbsent(key, value); + public void setTemplateImageTag(String templateImageTag) { + addParam(GenerateParam.templateImageTag, templateImageTag); } - - public void addParam(ParamKey paramKey, T value) { - addParam(paramKey.getKey(), value); + public String getBackgroundFormatName() { + return getParam(GenerateParam.backgroundFormatName); } - public T getParam(ParamKey paramKey) { - return (T) getParam(paramKey.getKey()); + public String getTemplateFormatName() { + return getParam(GenerateParam.templateFormatName); } - public T getOrDefault(ParamKey paramKey, T defaultValue) { - return (T) getOrDefault(paramKey.getKey(), defaultValue); + public boolean getObfuscate() { + return getParam(GenerateParam.obfuscate); } + public String getType() { + return getParam(GenerateParam.type); + } + + public String getBackgroundImageTag() { + return getParam(GenerateParam.backgroundImageTag); + } + + public String getTemplateImageTag() { + return getParam(GenerateParam.templateImageTag); + } + + public static Builder builder() { return new Builder(); } @@ -105,7 +110,6 @@ public class GenerateParam { private String type = CaptchaTypeConstant.SLIDER; private String backgroundImageTag; private String templateImageTag; - private AnyMap param = new AnyMap(); private Builder() { } @@ -140,20 +144,15 @@ public class GenerateParam { return this; } - public Builder param(AnyMap param) { - this.param = param; - return this; - } public GenerateParam build() { GenerateParam generateParam = new GenerateParam(); - generateParam.backgroundFormatName = backgroundFormatName; - generateParam.templateFormatName = templateFormatName; - generateParam.obfuscate = obfuscate; - generateParam.type = type; - generateParam.backgroundImageTag = backgroundImageTag; - generateParam.templateImageTag = templateImageTag; - generateParam.param = param; + generateParam.setBackgroundFormatName(backgroundFormatName); + generateParam.setTemplateFormatName(templateFormatName); + generateParam.setObfuscate(obfuscate); + generateParam.setType(type); + generateParam.setBackgroundImageTag(backgroundImageTag); + generateParam.setTemplateImageTag(templateImageTag); return generateParam; } } diff --git a/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ParamKey.java b/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ParamKey.java deleted file mode 100644 index a5d4780..0000000 --- a/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ParamKey.java +++ /dev/null @@ -1,12 +0,0 @@ -package cloud.tianai.captcha.generator.common.model.dto; - -/** - * @Author: 天爱有情 - * @date 2024/11/20 11:34 - * @Description 此接口的作用是在给 {@link GenerateParam} 添加/获取参数时做一个类型限制和转换 - */ -public interface ParamKey { - - String getKey(); - -} diff --git a/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ParamKeyEnum.java b/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ParamKeyEnum.java index 1fef4dc..6606b11 100644 --- a/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ParamKeyEnum.java +++ b/tianai-captcha/src/main/java/cloud/tianai/captcha/generator/common/model/dto/ParamKeyEnum.java @@ -1,6 +1,7 @@ package cloud.tianai.captcha.generator.common.model.dto; +import cloud.tianai.captcha.common.ParamKey; import lombok.AllArgsConstructor; import lombok.Getter; @@ -15,7 +16,8 @@ public class ParamKeyEnum implements ParamKey { public static final ParamKey CLICK_INTERFERENCE_COUNT = new ParamKeyEnum<>("interferenceCount"); /** 读取字体时,可指定字体TAG,可用于给不同的验证码指定不同的字体包.*/ public static final ParamKey FONT_TAG = new ParamKeyEnum<>("fontTag"); - + /** 容错值.*/ + public static final ParamKey TOLERANT = new ParamKeyEnum<>("tolerant"); /** 验证码ID,内部使用.*/ public static final ParamKey ID = new ParamKeyEnum<>("_id"); diff --git a/tianai-captcha/src/main/java/cloud/tianai/captcha/validator/common/model/dto/Drives.java b/tianai-captcha/src/main/java/cloud/tianai/captcha/validator/common/model/dto/Drives.java index 2ac6061..fa333a1 100644 --- a/tianai-captcha/src/main/java/cloud/tianai/captcha/validator/common/model/dto/Drives.java +++ b/tianai-captcha/src/main/java/cloud/tianai/captcha/validator/common/model/dto/Drives.java @@ -1,18 +1,7 @@ package cloud.tianai.captcha.validator.common.model.dto; -import lombok.Data; +import cloud.tianai.captcha.common.AnyMap; + +public class Drives extends AnyMap { -@Data -public class Drives { - private Integer hardwareConcurrency; - private Boolean hasXhr = false; - private String href; - private String language; - private Long start; - private Long now; - private String platform; - private Integer scripts; - private String userAgent; - private Integer windowHeight; - private Integer windowWidth; } diff --git a/tianai-captcha/src/main/java/cloud/tianai/captcha/validator/common/model/dto/MatchParam.java b/tianai-captcha/src/main/java/cloud/tianai/captcha/validator/common/model/dto/MatchParam.java index 2e4f8b7..ee994bb 100644 --- a/tianai-captcha/src/main/java/cloud/tianai/captcha/validator/common/model/dto/MatchParam.java +++ b/tianai-captcha/src/main/java/cloud/tianai/captcha/validator/common/model/dto/MatchParam.java @@ -1,5 +1,7 @@ package cloud.tianai.captcha.validator.common.model.dto; +import cloud.tianai.captcha.common.AnyMap; +import cloud.tianai.captcha.common.ParamKey; import lombok.Data; import lombok.NoArgsConstructor; @@ -10,22 +12,35 @@ import lombok.NoArgsConstructor; */ @Data @NoArgsConstructor -public class MatchParam { - /** 轨迹信息. */ - private ImageCaptchaTrack track; - /** 检测到的设备信息. */ - private Drives drives; - /** 留一个扩展属性. */ - private Object extendData; +public class MatchParam extends AnyMap { + private static final ParamKey track = () -> "track"; + private static final ParamKey drives = () -> "drives"; + + + public ImageCaptchaTrack getTrack() { + return getParam(MatchParam.track); + } + + public Drives getDrives() { + return getParam(MatchParam.drives); + } + + public void setTrack(ImageCaptchaTrack track) { + addParam(MatchParam.track, track); + } + + public void setDrives(Drives drives) { + addParam(MatchParam.drives, drives); + } public MatchParam(ImageCaptchaTrack track) { - this.track = track; + this.setTrack(track); } public MatchParam(ImageCaptchaTrack track, Drives drives) { - this.track = track; - this.drives = drives; + this.setTrack(track); + this.setDrives(drives); } } diff --git a/tianai-captcha/src/test/java/example/readme/TACBuilderTest.java b/tianai-captcha/src/test/java/example/readme/TACBuilderTest.java index 512a46d..9747f64 100644 --- a/tianai-captcha/src/test/java/example/readme/TACBuilderTest.java +++ b/tianai-captcha/src/test/java/example/readme/TACBuilderTest.java @@ -26,7 +26,8 @@ public class TACBuilderTest { // template1.put(StandardSliderImageCaptchaGenerator.TEMPLATE_ACTIVE_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, "/active.png")); // template1.put(StandardSliderImageCaptchaGenerator.TEMPLATE_FIXED_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, "/fixed.png")); - ImageCaptchaApplication application = TACBuilder.builder(new LocalMemoryResourceStore()) + ImageCaptchaApplication application = TACBuilder.builder() + .setResourceStore(new LocalMemoryResourceStore()) // 加载系统自带的默认资源 .addDefaultTemplate() // 设置验证码过期时间