kaptcha 是一个非常实用的验证码生成工具。有了它,你可以生成各种样式的验证码,因为它是可配置的。kaptcha工作的原理是调用 com.google.code.kaptcha.servlet.KaptchaServlet,生成一个图片。同时将生成的验证码字符串放到 HttpSession中。
使用kaptcha可以方便的配置:
- <dependency>
- <groupId>pro.fessionalgroupId>
- <artifactId>kaptchaartifactId>
- <version>2.3.3version>
- dependency>
- <dependency>
- <groupId>com.jhlabsgroupId>
- <artifactId>filtersartifactId>
- <version>2.0.235version>
- dependency>
-
-
- import java.util.Properties;
-
- import org.springframework.context.annotation.Bean;
- import org.springframework.stereotype.Component;
-
- import com.google.code.kaptcha.impl.DefaultKaptcha;
- import com.google.code.kaptcha.util.Config;
-
- @Component
- public class KaptchaConfig {
-
- @Bean
- public DefaultKaptcha getDefaultKaptcha() {
- DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
- Properties properties = new Properties();
- // 图片边框
- properties.setProperty("kaptcha.border", "no");
- // 边框颜色
- properties.setProperty("kaptcha.border.color", "black");
- //边框厚度
- properties.setProperty("kaptcha.border.thickness", "1");
- // 图片宽
- properties.setProperty("kaptcha.image.width", "200");
- // 图片高
- properties.setProperty("kaptcha.image.height", "50");
- //图片实现类
- properties.setProperty("kaptcha.producer.impl", "com.google.code.kaptcha.impl.DefaultKaptcha");
- //文本实现类
- properties.setProperty("kaptcha.textproducer.impl", "com.google.code.kaptcha.text.impl.DefaultTextCreator");
- //文本集合,验证码值从此集合中获取
- properties.setProperty("kaptcha.textproducer.char.string", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
- //验证码长度
- properties.setProperty("kaptcha.textproducer.char.length", "4");
- //字体
- properties.setProperty("kaptcha.textproducer.font.names", "宋体");
- //字体颜色
- properties.setProperty("kaptcha.textproducer.font.color", "black");
- //文字间隔
- properties.setProperty("kaptcha.textproducer.char.space", "5");
- //干扰实现类
- properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.DefaultNoise");
- //干扰颜色
- properties.setProperty("kaptcha.noise.color", "blue");
- //干扰图片样式
- properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.WaterRipple");
- //背景实现类
- properties.setProperty("kaptcha.background.impl", "com.google.code.kaptcha.impl.DefaultBackground");
- //背景颜色渐变,结束颜色
- properties.setProperty("kaptcha.background.clear.to", "white");
- //文字渲染器
- properties.setProperty("kaptcha.word.impl", "com.google.code.kaptcha.text.impl.DefaultWordRenderer");
- Config config = new Config(properties);
- defaultKaptcha.setConfig(config);
- return defaultKaptcha;
- }
-
- }
在获取验证码的类中直接引入配置类即可
/** * 验证码类:Google Kaptcha */ @Autowired DefaultKaptcha defaultKaptcha;
- /**
- * 获取图片验证码
- *
- * @return
- * @throws Exception
- */
- public RspObjectBO
verifyCodeGet(VerifyCodeReqBO reqBO) throws Exception { - RspObjectBO
res = new RspObjectBO<>(); - VerifyCodeRspBO data = new VerifyCodeRspBO();
- String verifyId = CommonUtils.getUUID();
- String createText = defaultKaptcha.createText();
- log.info("验证码内容:{}", createText);
- BufferedImage bi = defaultKaptcha.createImage(createText);
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- ImageIO.write(bi, "jpeg", stream);
- String verifyCode = Base64.encode(stream.toByteArray());
- stream.flush();
- stream.close();
- RBucket
rBucket = redissonClient.getBucket(RedisKeyConstants.VerifyCodeKey + verifyId, StringCodec.INSTANCE); - if (Objects.nonNull(reqBO.getDev_type()) && reqBO.getDev_type().equals(DeviceTypeEnum.Terminal_WX_Xcx.getType())) {
- rBucket = redissonClient.getBucket(RedisKeyConstants.VerifyCodeKey + reqBO.getDev_type() + verifyId, StringCodec.INSTANCE);
- }
- rBucket.set(createText, 3, TimeUnit.MINUTES);
- data.setVerifyid(verifyId);
- data.setVerifydata(verifyCode);
- res.setData(data);
- return res;
- }
- import cn.hutool.core.codec.Base64;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
-
- import javax.imageio.ImageIO;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- import java.awt.*;
- import java.awt.image.BufferedImage;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.security.SecureRandom;
- import java.util.Random;
-
- public class RandomValidateCodeUtil {
-
-
- private static final String RANDOMCODEKEY = "RANDOMVALIDATECODEKEY";//放到session中的key
- private static final Logger logger = LoggerFactory.getLogger(RandomValidateCodeUtil.class);
-
- // private String randString = "0123456789";//随机产生只有数字的字符串 private String
- //private String randString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生只有字母的字符串
- private String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生数字与字母组合的字符串
-
- private int width = 95;// 图片宽
- private int height = 30;// 图片高
- private int lineSize = 40;// 干扰线数量
- private int stringNum = 4;// 随机产生字符数量
- private Random random = new SecureRandom();
-
- /**
- * 获得字体
- */
- private Font getFont() {
- return new Font("Fixedsys", Font.CENTER_BASELINE, 18);
- }
-
- /**
- * 获得颜色
- */
- private Color getRandColor(int fc, int bc) {
- if (fc > 255) {
- fc = 255;
- }
- if (bc > 255) {
- bc = 255;
- }
- int r = fc + random.nextInt(bc - fc - 16);
- int g = fc + random.nextInt(bc - fc - 14);
- int b = fc + random.nextInt(bc - fc - 18);
- return new Color(r, g, b);
- }
-
- /**
- * 生成随机图片 存储到session中
- */
- public void getRandomCode(HttpServletRequest request, HttpServletResponse response) {
-
- HttpSession session = request.getSession();
-
- // BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
- BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
-
- // 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
- Graphics g = image.getGraphics();
-
- g.fillRect(0, 0, width, height);//图片大小
-
- g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));//字体大小
-
- g.setColor(getRandColor(110, 133));//字体颜色
-
- // 绘制干扰线
- for (int i = 0; i <= lineSize; i++) {
- drawLine(g);
- }
-
- // 绘制随机字符
- String randomString = "";
-
- for (int i = 1; i <= stringNum; i++) {
- randomString = drawString(g, randomString, i);
- }
- //将生成的随机字符串保存到session中
- session.removeAttribute(RANDOMCODEKEY);
- session.setAttribute(RANDOMCODEKEY, randomString);
- g.dispose();
- try {
- // 将内存中的图片通过流动形式输出到客户端
- ImageIO.write(image, "JPEG", response.getOutputStream());
- } catch (Exception e) {
- logger.error("将内存中的图片通过流动形式输出到客户端失败>>>> ", e);
- }
-
- }
-
- /**
- * 生成随机图片验证码
- */
- private String getRandomCode() throws IOException {
- // BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
- BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
- // 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
- Graphics g = image.getGraphics();
- g.fillRect(0, 0, width, height);//图片大小
- g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));//字体大小
- g.setColor(getRandColor(110, 133));//字体颜色
- // 绘制干扰线
- for (int i = 0; i <= lineSize; i++) {
- drawLine(g);
- }
- // 绘制随机字符
- String randomString = "";
-
- for (int i = 1; i <= stringNum; i++) {
- randomString = drawString(g, randomString, i);
- }
- g.dispose();
- //返回base64图片
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- ImageIO.write(image, "jpeg", stream);
- String verifiCode = Base64.encode(stream.toByteArray());
- stream.flush();
- stream.close();
- return verifiCode;
- }
-
- /**
- * 绘制字符串
- */
- private String drawString(Graphics g, String randomString, int i) {
- g.setFont(getFont());
- g.setColor(new Color(random.nextInt(101), random.nextInt(111), random
- .nextInt(121)));
- String rand = String.valueOf(getRandomString(random.nextInt(randString
- .length())));
- randomString += rand;
- g.translate(random.nextInt(3), random.nextInt(3));
- g.drawString(rand, 13 * i, 16);
- return randomString;
- }
-
- /**
- * 绘制干扰线
- */
- private void drawLine(Graphics g) {
-
- int x = random.nextInt(width);
- int y = random.nextInt(height);
-
- int xl = random.nextInt(13);
- int yl = random.nextInt(15);
-
- g.drawLine(x, y, x + xl, y + yl);
-
- }
-
- /**
- * 获取随机的字符
- */
- private String getRandomString(int num) {
- return String.valueOf(randString.charAt(num));
- }
-
- public static void main(String[] args) throws IOException {
- RandomValidateCodeUtil randomValidateCodeUtil = new RandomValidateCodeUtil();
- System.out.println(randomValidateCodeUtil.getRandomCode());
- }
- }
- @RequestMapping("getVerifiCode")
- @ResponseBody
- public void getVerifiCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
- /*
- 1.生成验证码
- 2.把验证码上的文本存在session中
- 3.把验证码图片发送给客户端
- */
- ImageVerificationCode ivc = new ImageVerificationCode(); //用我们的验证码类,生成验证码类对象
- BufferedImage image = ivc.getImage(); //获取验证码
- request.getSession().setAttribute("text", ivc.getText()); //将验证码的文本存在session中
- ivc.output(image, response.getOutputStream());//将验证码图片响应给客户端
- }
Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。
Hutool中的工具方法来自每个用户的精雕细琢,它涵盖了Java开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当;
Hutool是项目中“util”包友好的替代,它节省了开发人员对项目中公用类和公用工具方法的封装时间,使开发专注于业务,同时可以最大限度的避免封装不完善带来的bug。
- <dependency>
- <groupId>com.xiaoleilugroupId>
- <artifactId>hutool-allartifactId>
- <version>3.2.3version>
- dependency>
验证码功能位于cn.hutool.captcha包中,核心接口为ICaptcha,此接口定义了以下方法:
●createCode 创建验证码,实现类需同时生成随机验证码字符串和验证码图片
●getCode 获取验证码的文字内容
●verify 验证验证码是否正确,建议忽略大小写
●write 将验证码写出到目标流中
其中write方法只有一个OutputStream,ICaptcha实现类可以根据这个方法封装写出到文件等方法。AbstractCaptcha为一个ICaptcha抽象实现类,此类实现了验证码文本生成、非大小写敏感的验证、写出到流和文件等方法,通过继承此抽象类只需实现createImage方法定义图形生成规则即可。
LineCaptcha线段干扰的验证码

- //定义图形验证码的长和宽
- LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
-
- //图形验证码写出,可以写出到文件,也可以写出到流
- lineCaptcha.write("d:/line.png");
- //输出code
- Console.log(lineCaptcha.getCode());
- //验证图形验证码的有效性,返回boolean值
- lineCaptcha.verify("1234");
-
- //重新生成验证码
- lineCaptcha.createCode();
- lineCaptcha.write("d:/line.png");
- //新的验证码
- Console.log(lineCaptcha.getCode());
- //验证图形验证码的有效性,返回boolean值
- lineCaptcha.verify("1234");
CircleCaptcha圆圈干扰验证码

- //定义图形验证码的长、宽、验证码字符数、干扰元素个数
-
- CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);
-
- //CircleCaptcha captcha = new CircleCaptcha(200, 100, 4, 20);
-
- //图形验证码写出,可以写出到文件,也可以写出到流
-
- captcha.write("d:/circle.png");
-
- //验证图形验证码的有效性,返回boolean值
-
- captcha.verify("1234");
ShearCaptcha扭曲干扰验证码

- //定义图形验证码的长、宽、验证码字符数、干扰线宽度
-
- ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 100, 4, 4);
-
- //ShearCaptcha captcha = new ShearCaptcha(200, 100, 4, 4);
-
- //图形验证码写出,可以写出到文件,也可以写出到流
-
- captcha.write("d:/shear.png");
-
- //验证图形验证码的有效性,返回boolean值
-
- captcha.verify("1234");
自定义验证码
有时候标准的验证码不满足要求,比如我们希望使用纯字母的验证码、纯数字的验证码、加减乘除的验证码,此时我们就要自定义CodeGenerator
- // 自定义纯数字的验证码(随机4位数字,可重复)
- RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
- LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
- lineCaptcha.setGenerator(randomGenerator);
- // 重新生成code
- lineCaptcha.createCode();
- ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 45, 4, 4);
- // 自定义验证码内容为四则运算方式
- captcha.setGenerator(new MathGenerator());
- // 重新生成code
- captcha.createCode();