U 修改资源读取和存储模块

升级版本为1.2
This commit is contained in:
liushaofeng
2021-08-07 17:16:57 +08:00
parent c5260356de
commit b56919f17d
14 changed files with 702 additions and 223 deletions
@@ -3,9 +3,6 @@ package cloud.tianai.captcha.template.slider;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
@@ -25,12 +22,23 @@ public class CacheSliderCaptchaTemplate implements SliderCaptchaTemplate {
private AtomicInteger pos = new AtomicInteger(0);
private SliderCaptchaTemplate target;
private int size;
/** 等待时间,一般报错或者拉取为空时会休眠一段时间再试. */
private int waitTime = 1000;
/** 调度器检查缓存的间隔时间. */
private int period = 100;
public CacheSliderCaptchaTemplate(SliderCaptchaTemplate target, int size) {
this.target = target;
this.size = size;
}
public CacheSliderCaptchaTemplate(SliderCaptchaTemplate target, int size, int waitTime, int period) {
this.target = target;
this.size = size;
this.waitTime = waitTime;
this.period = period;
}
/**
* 记的初始化调度器
*/
@@ -57,22 +65,26 @@ public class CacheSliderCaptchaTemplate implements SliderCaptchaTemplate {
pos.incrementAndGet();
}
} else {
// 休眠500毫秒
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException ignored) {
}
sleep();
}
}
} catch (Exception e) {
// cache所有
log.error("缓存队列扫描时出错, ex", e);
// 休眠
sleep();
}
}, 0, 100, TimeUnit.MILLISECONDS);
}, 0, period, TimeUnit.MILLISECONDS);
log.info("缓存滑块验证码调度器初始化完成: size:{}", size);
}
private void sleep() {
try {
TimeUnit.MILLISECONDS.sleep(waitTime);
} catch (InterruptedException ignored) {
}
}
@SneakyThrows
@Override
public SliderCaptchaInfo getSlideImageInfo() {
@@ -88,60 +100,21 @@ public class CacheSliderCaptchaTemplate implements SliderCaptchaTemplate {
}
@Override
public void addResource(URL url) {
target.addResource(url);
public SliderCaptchaInfo getSlideImageInfo(String targetFormatName, String matrixFormatName) {
return target.getSlideImageInfo(targetFormatName, matrixFormatName);
}
@Override
public void addTemplate(Map<String, URL> template) {
target.addTemplate(template);
}
@Override
public void setResource(List<URL> resources) {
target.setResource(resources);
}
@Override
public void setTemplates(List<Map<String, URL>> imageTemplates) {
target.setTemplates(imageTemplates);
}
@Override
public void deleteResource(URL resource) {
target.deleteResource(resource);
}
@Override
public List<URL> listResources() {
return target.listResources();
}
@Override
public void clearResources() {
target.clearResources();
}
@Override
public void deleteTemplate(Map<String, URL> template) {
target.deleteTemplate(template);
}
@Override
public List<Map<String, URL>> listTemplates() {
return target.listTemplates();
}
@Override
public void clearTemplates() {
target.clearTemplates();
}
@Override
public boolean percentageContrast(Float newPercentage, Float oriPercentage) {
return target.percentageContrast(newPercentage, oriPercentage);
}
@Override
public SliderCaptchaResourceManager getSlideImageResourceManager() {
return target.getSlideImageResourceManager();
}
// public static void main(String[] args) throws InterruptedException {
// SliderCaptchaTemplate captchaTemplate = new DefaultSliderCaptchaTemplate("jpeg", "png", true);
@@ -0,0 +1,99 @@
package cloud.tianai.captcha.template.slider;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* @Author: 天爱有情
* @date 2021/8/7 15:43
* @Description 默认的资源存储
*/
public class DefaultResourceStore implements ResourceStore {
/**
* 模板资源.
*/
private List<Map<String, Resource>> templateResourceList = new ArrayList<>(2);
/**
* resource.
*/
private List<Resource> resourceList = new ArrayList<>(20);
@Override
public void addResource(Resource resource) {
resourceList.add(resource);
}
@Override
public void setResource(List<Resource> resources) {
resourceList = new ArrayList<>(resources);
}
@Override
public boolean deleteResource(Resource resource) {
return resourceList.remove(resource);
}
@Override
public void clearResources() {
resourceList.clear();
}
@Override
public void addTemplate(Map<String, Resource> template) {
templateResourceList.add(template);
}
@Override
public void setTemplates(List<Map<String, Resource>> templateResource) {
templateResourceList = new ArrayList<>(templateResource);
}
@Override
public void deleteTemplate(Map<String, Resource> template) {
templateResourceList.remove(template);
}
@Override
public void clearTemplates() {
templateResourceList.clear();
}
@Override
public List<Resource> listResources() {
return Collections.unmodifiableList(resourceList);
}
@Override
public List<Map<String, Resource>> listTemplates() {
return Collections.unmodifiableList(templateResourceList);
}
@Override
public int getResourceCount() {
return resourceList.size();
}
@Override
public int getTemplateCount() {
return templateResourceList.size();
}
@Override
public Resource getResourceByIndex(int index) {
if (index < 0 || index > resourceList.size() - 1) {
throw new IllegalArgumentException("错误的index");
}
return resourceList.get(index);
}
@Override
public Map<String, Resource> getTemplateByIndex(int index) {
if (index < 0 || index > templateResourceList.size() - 1) {
throw new IllegalArgumentException("错误的index");
}
return templateResourceList.get(index);
}
}
@@ -0,0 +1,106 @@
package cloud.tianai.captcha.template.slider;
import cloud.tianai.captcha.template.slider.provider.ClassPathResourceProvider;
import cloud.tianai.captcha.template.slider.provider.URLResourceProvider;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
/**
* @Author: 天爱有情
* @date 2021/8/7 15:35
* @Description 默认的滑块验证码资源管理
*/
public class DefaultSliderCaptchaResourceManager implements SliderCaptchaResourceManager {
private ResourceStore resourceStore;
private List<ResourceProvider> resourceProviderList = new ArrayList<>(8);
public DefaultSliderCaptchaResourceManager() {
init();
}
public DefaultSliderCaptchaResourceManager(ResourceStore resourceStore) {
this.resourceStore = resourceStore;
init();
}
private void init() {
if (this.resourceStore == null) {
this.resourceStore = new DefaultResourceStore();
}
// 注入一些默认的提供者
registerResourceProvider(new URLResourceProvider());
registerResourceProvider(new ClassPathResourceProvider());
}
@Override
public Map<String, Resource> randomGetTemplate() {
int count = resourceStore.getTemplateCount();
if (count < 1) {
throw new IllegalStateException("随机获取模板错误,store中模板为空");
}
if (count == 1) {
return resourceStore.getTemplateByIndex(0);
}
int randomIndex = ThreadLocalRandom.current().nextInt(count);
return resourceStore.getTemplateByIndex(randomIndex);
}
@Override
public Resource randomGetResource() {
int count = resourceStore.getResourceCount();
if (count < 1) {
throw new IllegalStateException("随机获取资源错误,store中资源为空");
}
if (count == 1) {
return resourceStore.getResourceByIndex(0);
}
int randomIndex = ThreadLocalRandom.current().nextInt(count);
return resourceStore.getResourceByIndex(randomIndex);
}
@Override
public InputStream getResourceInputStream(Resource resource) {
for (ResourceProvider resourceProvider : resourceProviderList) {
if (resourceProvider.supported(resource.getType())) {
return resourceProvider.getResourceInputStream(resource);
}
}
throw new IllegalStateException("没有找到Resource [" + resource.getType() + "]对应的资源提供者");
}
@Override
public List<ResourceProvider> listResourceProviders() {
return Collections.unmodifiableList(resourceProviderList);
}
@Override
public void registerResourceProvider(ResourceProvider resourceProvider) {
deleteResourceProviderByName(resourceProvider.getName());
resourceProviderList.add(resourceProvider);
}
@Override
public boolean deleteResourceProviderByName(String name) {
return resourceProviderList.removeIf(r -> r.getName().equals(name));
}
@Override
public void setResourceStore(ResourceStore resourceStore) {
this.resourceStore = resourceStore;
}
@Override
public ResourceStore getResourceStore() {
return resourceStore;
}
}
@@ -1,5 +1,6 @@
package cloud.tianai.captcha.template.slider;
import cloud.tianai.captcha.template.slider.provider.ClassPathResourceProvider;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@@ -11,9 +12,12 @@ import java.awt.image.ColorModel;
import java.awt.image.PixelGrabber;
import java.awt.image.WritableRaster;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import java.util.*;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
/**
@@ -33,132 +37,38 @@ public class DefaultSliderCaptchaTemplate implements SliderCaptchaTemplate {
*/
public static final String DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH = "META-INF/cut-image/template";
public static final String ACTIVE_IMAGE_NAME = "active.png";
public static final String FIXED_IMAGE_NAME = "fixed.png";
public static final String MATRIX_IMAGE_NAME = "matrix.png";
/**
* resource图片.
*/
private List<URL> resourceImageFiles = new ArrayList<>(20);
/**
* 模板图片.
*/
private List<Map<String, URL>> templateImageFiles = new ArrayList<>(2);
private final SliderCaptchaResourceManager sliderCaptchaResourceManager;
protected String targetFormatName = "jpeg";
protected String matrixFormatName = "png";
public void initDefaultResource() {
ResourceStore resourceStore = sliderCaptchaResourceManager.getResourceStore();
// 添加一些系统的资源文件
addResource(getClassLoader().getResource(DEFAULT_SLIDER_IMAGE_RESOURCE_PATH.concat("/1.jpg")));
resourceStore.addResource(new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_RESOURCE_PATH.concat("/1.jpg")));
// 添加一些系统的 模板文件
Map<String, URL> template1 = new HashMap<>(4);
template1.put(ACTIVE_IMAGE_NAME, getClassLoader().getResource(DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/1/active.png")));
template1.put(FIXED_IMAGE_NAME, getClassLoader().getResource(DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/1/fixed.png")));
template1.put(MATRIX_IMAGE_NAME, getClassLoader().getResource(DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/1/matrix.png")));
addTemplate(template1);
Map<String, Resource> template1 = new HashMap<>(4);
template1.put(SliderCaptchaConstant.TEMPLATE_ACTIVE_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/1/active.png")));
template1.put(SliderCaptchaConstant.TEMPLATE_FIXED_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/1/fixed.png")));
template1.put(SliderCaptchaConstant.TEMPLATE_MATRIX_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/1/matrix.png")));
resourceStore.addTemplate(template1);
Map<String, URL> template2 = new HashMap<>(4);
template2.put(ACTIVE_IMAGE_NAME, getClassLoader().getResource(DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/2/active.png")));
template2.put(FIXED_IMAGE_NAME, getClassLoader().getResource(DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/2/fixed.png")));
template2.put(MATRIX_IMAGE_NAME, getClassLoader().getResource(DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/2/matrix.png")));
addTemplate(template2);
Map<String, Resource> template2 = new HashMap<>(4);
template2.put(SliderCaptchaConstant.TEMPLATE_ACTIVE_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/2/active.png")));
template2.put(SliderCaptchaConstant.TEMPLATE_FIXED_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/2/fixed.png")));
template2.put(SliderCaptchaConstant.TEMPLATE_MATRIX_IMAGE_NAME, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_TEMPLATE_PATH.concat("/2/matrix.png")));
resourceStore.addTemplate(template2);
}
public DefaultSliderCaptchaTemplate(boolean initDefaultResource) {
// 加载系统资源文件
public DefaultSliderCaptchaTemplate(SliderCaptchaResourceManager sliderCaptchaResourceManager, boolean initDefaultResource) {
this.sliderCaptchaResourceManager = sliderCaptchaResourceManager;
if (initDefaultResource) {
initDefaultResource();
}
}
public DefaultSliderCaptchaTemplate(String targetFormatName, String matrixFormatName, boolean initDefaultResource) {
this.targetFormatName = targetFormatName;
this.matrixFormatName = matrixFormatName;
if (initDefaultResource) {
initDefaultResource();
}
}
public DefaultSliderCaptchaTemplate(String targetFormatName,
String matrixFormatName,
List<URL> r,
List<Map<String, URL>> t,
boolean initDefaultResource) {
this.targetFormatName = targetFormatName;
this.matrixFormatName = matrixFormatName;
resourceImageFiles = r;
templateImageFiles = t;
if (initDefaultResource) {
initDefaultResource();
}
}
public DefaultSliderCaptchaTemplate(List<URL> r, List<Map<String, URL>> t, boolean initDefaultResource) {
resourceImageFiles = r;
templateImageFiles = t;
if (initDefaultResource) {
initDefaultResource();
}
}
@Override
public void addResource(URL url) {
resourceImageFiles.remove(url);
resourceImageFiles.add(url);
}
@Override
public void setResource(List<URL> resources) {
resourceImageFiles = resources;
}
@Override
public void setTemplates(List<Map<String, URL>> imageTemplates) {
templateImageFiles = imageTemplates;
}
@Override
public void deleteResource(URL resource) {
resourceImageFiles.remove(resource);
}
@Override
public List<URL> listResources() {
return Collections.unmodifiableList(resourceImageFiles);
}
@Override
public void clearResources() {
resourceImageFiles.clear();
}
@Override
public void deleteTemplate(Map<String, URL> template) {
templateImageFiles.remove(template);
}
@Override
public List<Map<String, URL>> listTemplates() {
return Collections.unmodifiableList(templateImageFiles);
}
@Override
public void clearTemplates() {
templateImageFiles.clear();
}
@Override
public void addTemplate(Map<String, URL> template) {
templateImageFiles.remove(template);
templateImageFiles.add(template);
}
private static ClassLoader getClassLoader() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
@@ -173,27 +83,26 @@ public class DefaultSliderCaptchaTemplate implements SliderCaptchaTemplate {
@Override
public SliderCaptchaInfo getSlideImageInfo() {
return getSlideImageInfo(this.targetFormatName, this.matrixFormatName);
return getSlideImageInfo("jpeg", "png");
}
@SneakyThrows
@Override
public SliderCaptchaInfo getSlideImageInfo(String targetFormatName, String matrixFormatName) {
if (resourceImageFiles.isEmpty() || templateImageFiles.isEmpty()) {
log.warn("滑块验证码生成失败, 资源或模板为空,不能进行生成, 资源文件列表长度: {}, 模板文件列表长度: {}",
resourceImageFiles.size(), templateImageFiles.size());
return null;
}
URL resourceImage = getRandomResourceImage();
Map<String, URL> templateImages = getRandomTemplateImages();
BufferedImage cutBackground = warpFile2BufferedImage(resourceImage);
Map<String, Resource> templateImages = sliderCaptchaResourceManager.randomGetTemplate();
Resource resourceImage = sliderCaptchaResourceManager.randomGetResource();
BufferedImage cutBackground = warpFile2BufferedImage(sliderCaptchaResourceManager.getResourceInputStream(resourceImage));
// 拷贝一份图片
BufferedImage targetBackground = deepCopyBufferedImage(cutBackground);
BufferedImage fixedTemplate = warpFile2BufferedImage(getTemplateFile(templateImages, FIXED_IMAGE_NAME));
BufferedImage activeTemplate = warpFile2BufferedImage(getTemplateFile(templateImages, ACTIVE_IMAGE_NAME));
BufferedImage matrixTemplate = warpFile2BufferedImage(getTemplateFile(templateImages, MATRIX_IMAGE_NAME));
BufferedImage fixedTemplate = warpFile2BufferedImage(getTemplateFile(templateImages, SliderCaptchaConstant.TEMPLATE_FIXED_IMAGE_NAME));
BufferedImage activeTemplate = warpFile2BufferedImage(getTemplateFile(templateImages, SliderCaptchaConstant.TEMPLATE_ACTIVE_IMAGE_NAME));
BufferedImage matrixTemplate = warpFile2BufferedImage(getTemplateFile(templateImages, SliderCaptchaConstant.TEMPLATE_MATRIX_IMAGE_NAME));
// BufferedImage cutTemplate = warpFile2BufferedImage(getTemplateFile(templateImages, CUT_IMAGE_NAME));
// 获取随机的 x 和 y 轴
@@ -233,6 +142,11 @@ public class DefaultSliderCaptchaTemplate implements SliderCaptchaTemplate {
return newPercentage >= minTolerant && newPercentage <= maxTolerant;
}
@Override
public SliderCaptchaResourceManager getSlideImageResourceManager() {
return sliderCaptchaResourceManager;
}
private String transformBase64(BufferedImage bufferedImage, String formatName) {
byte[] data = null;
@@ -383,21 +297,14 @@ public class DefaultSliderCaptchaTemplate implements SliderCaptchaTemplate {
g2d.dispose();
}
private URL getTemplateFile(Map<String, URL> templateImages, String imageName) {
URL url = templateImages.get(imageName);
if (url == null) {
private InputStream getTemplateFile(Map<String, Resource> templateImages, String imageName) {
Resource resource = templateImages.get(imageName);
if (resource == null) {
throw new IllegalArgumentException("查找模板异常, 该模板下未找到 ".concat(imageName));
}
return url;
return sliderCaptchaResourceManager.getResourceInputStream(resource);
}
private Map<String, URL> getRandomTemplateImages() {
if (templateImageFiles.size() == 1) {
return templateImageFiles.get(0);
}
int templateNo = ThreadLocalRandom.current().nextInt(templateImageFiles.size());
return templateImageFiles.get(templateNo);
}
@SneakyThrows
private static BufferedImage warpFile2BufferedImage(URL resourceImage) {
@@ -407,23 +314,27 @@ public class DefaultSliderCaptchaTemplate implements SliderCaptchaTemplate {
return ImageIO.read(resourceImage);
}
private URL getRandomResourceImage() {
if (resourceImageFiles.size() == 1) {
return resourceImageFiles.get(0);
@SneakyThrows
private static BufferedImage warpFile2BufferedImage(InputStream resource) {
if (resource == null) {
throw new IllegalArgumentException("包装文件到 BufferedImage 失败, file不能为空");
}
int targetNo = ThreadLocalRandom.current().nextInt(resourceImageFiles.size());
return resourceImageFiles.get(targetNo);
return ImageIO.read(resource);
}
// public static void main(String[] args) throws InterruptedException {
// DefaultSliderCaptchaTemplate sliderCaptchaTemplate = new DefaultSliderCaptchaTemplate();
// // 生成滑块图片
// SliderCaptchaInfo slideImageInfo = sliderCaptchaTemplate.getSlideImageInfo();
// // 获取背景图片的base64
// String backgroundImage = slideImageInfo.getBackgroundImage();
// // 获取滑块图片
// slideImageInfo.getSliderImage();
// // 获取滑块被背景图片的百分比, (校验图片使用)
// Float xPercent = slideImageInfo.getXPercent();
// }
public static void main(String[] args) throws InterruptedException {
SliderCaptchaResourceManager sliderCaptchaResourceManager = new DefaultSliderCaptchaResourceManager();
DefaultSliderCaptchaTemplate sliderCaptchaTemplate = new DefaultSliderCaptchaTemplate(sliderCaptchaResourceManager, true);
// 生成滑块图片
SliderCaptchaInfo slideImageInfo = sliderCaptchaTemplate.getSlideImageInfo();
// 获取背景图片的base64
String backgroundImage = slideImageInfo.getBackgroundImage();
// 获取滑块图片
slideImageInfo.getSliderImage();
// 获取滑块被背景图片的百分比, (校验图片使用)
Float xPercent = slideImageInfo.getXPercent();
System.out.println(slideImageInfo);
}
}
@@ -0,0 +1,18 @@
package cloud.tianai.captcha.template.slider;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* @Author: 天爱有情
* @date 2021/8/7 15:15
* @Description 资源对象
*/
@Data
@AllArgsConstructor
public class Resource {
/** 类型. */
private String type;
/** 数据,传输给 {@link ResourceProvider} 的参数 */
public String data;
}
@@ -0,0 +1,34 @@
package cloud.tianai.captcha.template.slider;
import java.io.InputStream;
/**
* @Author: 天爱有情
* @date 2021/8/7 15:07
* @Description 资源提供者
*/
public interface ResourceProvider {
/**
* 获取资源
*
* @param data data
* @return InputStream
*/
InputStream getResourceInputStream(Resource data);
/**
* 是否支持
*
* @param type type
* @return boolean
*/
boolean supported(String type);
/**
* 放弃资源提供者名称
*
* @return String
*/
String getName();
}
@@ -0,0 +1,106 @@
package cloud.tianai.captcha.template.slider;
import java.util.List;
import java.util.Map;
public interface ResourceStore {
/**
* 添加资源
*
* @param resource 资源
*/
void addResource(Resource resource);
/**
* 设置资源
*
* @param resources resources
*/
void setResource(List<Resource> resources);
/**
* 删除资源
*
* @param resource resource
*/
boolean deleteResource(Resource resource);
/**
* 清除所有资源
*/
void clearResources();
/**
* 添加模板
*
* @param template template
*/
void addTemplate(Map<String, Resource> template);
/**
* 设置模板
*
* @param templateResource templateResource
*/
void setTemplates(List<Map<String, Resource>> templateResource);
/**
* 删除模板
*
* @param template template
*/
void deleteTemplate(Map<String, Resource> template);
/**
* 清除所有模板
*/
void clearTemplates();
/**
* 获取所有资源对象
*
* @return List<Resource>
*/
List<Resource> listResources();
/**
* 获取所有模板
*
* @return List<Map < String, Resource>>
*/
List<Map<String, Resource>> listTemplates();
/**
* 获取资源总数
*
* @return int
*/
int getResourceCount();
/**
* 获取模板count
*
* @return int
*/
int getTemplateCount();
/**
* 获取资源通过index
*
* @param index index
* @return Resource
*/
Resource getResourceByIndex(int index);
/**
* 获取模板通过indx
*
* @param index index
* @return Map<String, Resource>
*/
Map<String, Resource> getTemplateByIndex(int index);
}
@@ -0,0 +1,16 @@
package cloud.tianai.captcha.template.slider;
/**
* @Author: 天爱有情
* @date 2021/8/7 17:14
* @Description 滑块验证码常量
*/
public interface SliderCaptchaConstant {
/** 模板滑块固定名称. */
String TEMPLATE_ACTIVE_IMAGE_NAME = "active.png";
/** 模板凹槽固定名称. */
String TEMPLATE_FIXED_IMAGE_NAME = "fixed.png";
/** 模板背景固定名称. */
String TEMPLATE_MATRIX_IMAGE_NAME = "matrix.png";
}
@@ -0,0 +1,71 @@
package cloud.tianai.captcha.template.slider;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
/**
* @Author: 天爱有情
* @date 2021/8/7 15:26
* @Description 滑块验证码图片资源管理器
*/
public interface SliderCaptchaResourceManager {
/**
* 随机获取某个模板
*
* @return Map<String, Resource>
*/
Map<String, Resource> randomGetTemplate();
/**
* 随机获取某个资源对象
*
* @return Resource
*/
Resource randomGetResource();
/**
* 获取真正的资源流通过资源对象
*
* @param resource resource
* @return InputStream
*/
InputStream getResourceInputStream(Resource resource);
/**
* 获取所有资源提供者
*
* @return List<ResourceProvider>
*/
List<ResourceProvider> listResourceProviders();
/**
* 注册资源提供者
*
* @param resourceProvider 资源提供者
*/
void registerResourceProvider(ResourceProvider resourceProvider);
/**
* 删除资源提供者
*
* @param name 资源提供者名称
* @return ResourceProvider
*/
boolean deleteResourceProviderByName(String name);
/**
* 设置资源存储
*
* @param resourceStore resourceStore
*/
void setResourceStore(ResourceStore resourceStore);
/**
* 获取资源存储
*
* @return ResourceStore
*/
ResourceStore getResourceStore();
}
@@ -5,7 +5,7 @@ package cloud.tianai.captcha.template.slider;
* @date 2020/10/19 18:37
* @Description 滑块验证码模板
*/
public interface SliderCaptchaTemplate extends SliderCaptchaResource {
public interface SliderCaptchaTemplate {
/**
* 获取滑块验证码
@@ -14,6 +14,16 @@ public interface SliderCaptchaTemplate extends SliderCaptchaResource {
*/
SliderCaptchaInfo getSlideImageInfo();
/**
* 获取滑块验证码
*
* @param targetFormatName jpeg或者webp格式
* @param matrixFormatName png或者webp格式
* @return SliderCaptchaInfo
*/
SliderCaptchaInfo getSlideImageInfo(String targetFormatName, String matrixFormatName);
/**
* 百分比对比
*
@@ -22,4 +32,12 @@ public interface SliderCaptchaTemplate extends SliderCaptchaResource {
* @return true 成功 false 失败
*/
boolean percentageContrast(Float newPercentage, Float oriPercentage);
/**
* 获取滑块验证码资源管理器
*
* @return SliderCaptchaResourceManager
*/
SliderCaptchaResourceManager getSlideImageResourceManager();
}
@@ -0,0 +1,42 @@
package cloud.tianai.captcha.template.slider.provider;
import cloud.tianai.captcha.template.slider.Resource;
import cloud.tianai.captcha.template.slider.ResourceProvider;
import java.io.InputStream;
/**
* @Author: 天爱有情
* @date 2021/8/7 16:07
* @Description classPath
*/
public class ClassPathResourceProvider implements ResourceProvider {
public static final String NAME = "classpath";
@Override
public InputStream getResourceInputStream(Resource data) {
return getClassLoader().getResourceAsStream(data.getData());
}
@Override
public boolean supported(String type) {
return NAME.equalsIgnoreCase(type);
}
@Override
public String getName() {
return NAME;
}
private static ClassLoader getClassLoader() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
classLoader = ClassPathResourceProvider.getClassLoader();
}
if (classLoader == null) {
classLoader = ClassLoader.getSystemClassLoader();
}
return classLoader;
}
}
@@ -0,0 +1,35 @@
package cloud.tianai.captcha.template.slider.provider;
import cloud.tianai.captcha.template.slider.Resource;
import cloud.tianai.captcha.template.slider.ResourceProvider;
import lombok.SneakyThrows;
import java.io.InputStream;
import java.net.URL;
/**
* @Author: 天爱有情
* @date 2021/8/7 16:05
* @Description url
*/
public class URLResourceProvider implements ResourceProvider {
public static final String NAME = "URL";
@SneakyThrows
@Override
public InputStream getResourceInputStream(Resource data) {
URL url = new URL(data.getData());
return url.openStream();
}
@Override
public boolean supported(String type) {
return NAME.equalsIgnoreCase(type);
}
@Override
public String getName() {
return NAME;
}
}