提交 8498d1b9 编写于 作者: O o2null

Merge branch 'feature/mnistCaptcha' into 'develop'

add mnist capctha

See merge request o2oa/o2oa!1115
...@@ -101,18 +101,12 @@ public abstract class AbstractProcessor extends AbstractBaseProcessor { ...@@ -101,18 +101,12 @@ public abstract class AbstractProcessor extends AbstractBaseProcessor {
aeiObjects.entityManagerContainer().commit(); aeiObjects.entityManagerContainer().commit();
} }
return work.getId(); return work.getId();
} catch ( } catch (Exception e) {
Exception e) {
LOGGER.error(e); LOGGER.error(e);
return null; return null;
} }
} }
// private void arriveCleanManualTaskIdentityList(AeiObjects aeiObjects) {
// aeiObjects.getWork().setManualTaskIdentityList(new ArrayList<>());
// }
private void arriveCleanManualTaskIdentityMatrix(AeiObjects aeiObjects) { private void arriveCleanManualTaskIdentityMatrix(AeiObjects aeiObjects) {
aeiObjects.getWork().setManualTaskIdentityMatrix(new ManualTaskIdentityMatrix()); aeiObjects.getWork().setManualTaskIdentityMatrix(new ManualTaskIdentityMatrix());
} }
...@@ -332,9 +326,7 @@ public abstract class AbstractProcessor extends AbstractBaseProcessor { ...@@ -332,9 +326,7 @@ public abstract class AbstractProcessor extends AbstractBaseProcessor {
// 执行AfterInquireScript中的代码可能修改了data数据. // 执行AfterInquireScript中的代码可能修改了data数据.
aeiObjects.entityManagerContainer().commit(); aeiObjects.entityManagerContainer().commit();
} }
} catch ( } catch (Exception e) {
Exception e) {
LOGGER.error(e); LOGGER.error(e);
} }
return results; return results;
......
package com.x.program.center.jaxrs.captcha;
import com.x.base.core.project.exception.LanguagePromptException;
class ExceptionCreateCaptcha extends LanguagePromptException {
private static final long serialVersionUID = -326121174563758109L;
ExceptionCreateCaptcha() {
super("create captcha error.");
}
}
package com.x.program.center.jaxrs.captcha; package com.x.program.center.jaxrs.captcha;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64; import java.util.Base64;
import java.util.Optional;
import java.util.Properties; import java.util.Properties;
import java.util.Random;
import java.util.function.Function;
import java.util.stream.Stream;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import org.apache.commons.lang3.ArrayUtils;
import com.google.code.kaptcha.Constants; import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer; import com.google.code.kaptcha.Producer;
import com.google.code.kaptcha.impl.DefaultKaptcha; import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config; import com.google.code.kaptcha.util.Config;
import com.google.common.collect.Streams;
import com.x.base.core.container.EntityManagerContainer; import com.x.base.core.container.EntityManagerContainer;
import com.x.base.core.container.factory.EntityManagerContainerFactory; import com.x.base.core.container.factory.EntityManagerContainerFactory;
import com.x.base.core.entity.annotation.CheckPersistType; import com.x.base.core.entity.annotation.CheckPersistType;
import com.x.base.core.project.annotation.FieldDescribe; import com.x.base.core.project.annotation.FieldDescribe;
import com.x.base.core.project.bean.tuple.Pair;
import com.x.base.core.project.http.ActionResult; import com.x.base.core.project.http.ActionResult;
import com.x.base.core.project.logger.Logger; import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory; import com.x.base.core.project.logger.LoggerFactory;
import com.x.program.center.ThisApplication;
import com.x.program.center.core.entity.Captcha; import com.x.program.center.core.entity.Captcha;
class V2Create extends BaseAction { class V2Create extends BaseAction {
...@@ -27,33 +41,78 @@ class V2Create extends BaseAction { ...@@ -27,33 +41,78 @@ class V2Create extends BaseAction {
ActionResult<Wo> execute(Integer width, Integer height) throws Exception { ActionResult<Wo> execute(Integer width, Integer height) throws Exception {
try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) { try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
ActionResult<Wo> result = new ActionResult<>(); ActionResult<Wo> result = new ActionResult<>();
if (width <= 80 || width > 800) { final Integer adjustWidth = (width <= 80 || width > 800) ? 80 : width;
width = 80; final Integer adjustHeight = (height <= 30 || height > 800) ? 30 : height;
Optional<Optional<Pair<String, byte[]>>> optional = Stream.of(kaptcha, mnist)
.map(o -> o.apply(Pair.of(adjustWidth, adjustHeight))).filter(Optional::isPresent).findFirst();
if (optional.isEmpty()) {
throw new ExceptionCreateCaptcha();
} }
if (height <= 30 || height > 800) { Optional<Pair<String, byte[]>> opt = optional.get();
height = 30; if (opt.isEmpty()) {
throw new ExceptionCreateCaptcha();
} }
Producer producer = createProducer(width, height); Pair<String, byte[]> pair = opt.get();
// 生成随机字符串
String verifyCode = producer.createText();
// 生成图片
BufferedImage bufferedImage = producer.createImage(verifyCode);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", stream);
emc.beginTransaction(Captcha.class); emc.beginTransaction(Captcha.class);
Captcha captcha = new Captcha(); Captcha captcha = new Captcha();
captcha.setAnswer(verifyCode); captcha.setAnswer(pair.first());
emc.persist(captcha, CheckPersistType.all); emc.persist(captcha, CheckPersistType.all);
emc.commit(); emc.commit();
Wo wo = new Wo(); Wo wo = new Wo();
wo.setId(captcha.getId()); wo.setId(captcha.getId());
wo.setImage(Base64.getEncoder().encodeToString(stream.toByteArray())); wo.setImage(Base64.getEncoder().encodeToString(pair.second()));
result.setData(wo); result.setData(wo);
return result; return result;
} }
} }
private static Function<Pair<Integer, Integer>, Optional<Pair<String, byte[]>>> kaptcha = param -> {
Producer producer = createProducer(param.first(), param.second());
// 生成随机字符串
String verifyCode = producer.createText();
// 生成图片
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
BufferedImage bufferedImage = producer.createImage(verifyCode);
ImageIO.write(bufferedImage, "png", out);
return Optional.of(Pair.of(verifyCode, out.toByteArray()));
} catch (Exception | Error e) {
// catch all exception
LOGGER.warn("can not create captcha, use mnist image instead, com.google.code.kaptcha not available:{}.",
e.getMessage());
}
return Optional.empty();
};
private static Function<Pair<Integer, Integer>, Optional<Pair<String, byte[]>>> mnist = param -> {
Random random = new SecureRandom();
String verifyCode = random.nextInt(10) + "" + random.nextInt(10) + "" + random.nextInt(10) + ""
+ random.nextInt(10);
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
Character[] chars = ArrayUtils.toObject(verifyCode.toCharArray());
BufferedImage combined = new BufferedImage(28 * chars.length, 28, BufferedImage.TYPE_INT_RGB);
final File dir = new File(ThisApplication.context().path(), "WEB-INF/mnist");
Streams.mapWithIndex(Arrays.<Character>stream(chars), Pair::of).forEach(p -> {
BufferedImage image;
try {
image = ImageIO.read(new File(dir, p.first() + "_" + random.nextInt(10)));
combined.getGraphics().drawImage(image, (int) (28 * p.second()), 0, null);
} catch (IOException e) {
LOGGER.error(e);
}
});
BufferedImage overlay = new BufferedImage(param.first(), param.second(), BufferedImage.TYPE_INT_RGB);
overlay.createGraphics().drawRenderedImage(combined,
AffineTransform.getScaleInstance(overlay.getWidth() / (double) combined.getWidth(),
overlay.getHeight() / (double) combined.getHeight()));
ImageIO.write(overlay, "png", out);
return Optional.of(Pair.of(verifyCode, out.toByteArray()));
} catch (IOException e) {
LOGGER.error(e);
}
return Optional.empty();
};
public static class Wo { public static class Wo {
@FieldDescribe("标识") @FieldDescribe("标识")
...@@ -90,8 +149,6 @@ class V2Create extends BaseAction { ...@@ -90,8 +149,6 @@ class V2Create extends BaseAction {
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, "40"); properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, "40");
properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_STRING, "1234567890"); properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_STRING, "1234567890");
// properties.setProperty(Constants.KAPTCHA_WORDRENDERER_IMPL,
// "com.x.base.core.project.kaptcha.SimpleWordRenderer");
Config config = new Config(properties); Config config = new Config(properties);
DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
defaultKaptcha.setConfig(config); defaultKaptcha.setConfig(config);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册