通常网站或平台为了安全性考虑,会增加验证码的功能,以防遭遇恶意机器注册或软件暴力对密码刷字典破解,这里采用的是google的kaptcha进行了简单封装;创建验证码图片操作工具类;
pom.xml增加jar依赖
com.github.penggle
kaptcha
2.3.2
KaptchaUtils工具类
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;
/**
* @Description 创建验证码图片操作工具类
* @Author JL
* @Date 2019/08/05
* @Version V1.0
*/
public class KaptchaUtils {
/**
* 创建验证码对象,并设置样式
* @return
*/
private static DefaultKaptcha getDefaultKaptcha(){
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Config config = new Config(kaptchaCss());
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
/**
* 设置验证码图片生成的样式属性
* @return
*/
private static Properties kaptchaCss(){
Properties properties = new Properties();
properties.setProperty("kaptcha.border", "yes");
properties.setProperty("kaptcha.border.color", "105,179,90");
properties.setProperty("kaptcha.textproducer.font.color", "blue");
properties.setProperty("kaptcha.image.width", "110");
properties.setProperty("kaptcha.image.height", "40");
properties.setProperty("kaptcha.textproducer.font.size", "30");
properties.setProperty("kaptcha.session.key", "code");
properties.setProperty("kaptcha.textproducer.char.length", "4");
properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
return properties;
}
/**
* 创建验证码,返回验证码值与字节数组(字节数组用于向前端输出)
* @param defaultKaptcha
* @return
* @throws Exception
*/
private static KaptchaVo defaultKaptcha(DefaultKaptcha defaultKaptcha) throws Exception {
KaptchaVo vo = new KaptchaVo();
String createText = defaultKaptcha.createText();//生产验证码字符串并保存到session中
ByteArrayOutputStream jpegOutputStream = null;
try {
jpegOutputStream = new ByteArrayOutputStream();
//使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
BufferedImage challenge = defaultKaptcha.createImage(createText);
ImageIO.write(challenge, "jpg", jpegOutputStream);
vo.setCode(createText);
vo.setImgs(jpegOutputStream.toByteArray());
} catch (IllegalArgumentException e) {
throw e;
}finally{
if (jpegOutputStream != null) {
jpegOutputStream.flush();
jpegOutputStream.close();
}
}
return vo;
}
/**
* 创建验证码,并生成图片到指定位置,返回验证码值
* @param defaultKaptcha
* @param imgPath
* @return
* @throws Exception
*/
private static String defaultKaptcha(DefaultKaptcha defaultKaptcha, String imgPath) throws Exception {
String createText = defaultKaptcha.createText();//生产验证码字符串并保存到session中
BufferedOutputStream jpegOutputStream = null;
try {
jpegOutputStream = new BufferedOutputStream(new FileOutputStream(new File(imgPath)));
//使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
BufferedImage challenge = defaultKaptcha.createImage(createText);
ImageIO.write(challenge, "jpg", jpegOutputStream);
} catch (IllegalArgumentException e) {
throw e;
}finally{
if (jpegOutputStream != null) {
jpegOutputStream.flush();
jpegOutputStream.close();
}
}
return createText;
}
/**
* 创建验证码,返回验证码值与字节数组(字节数组用于向前端输出)
* @return
* @throws Exception
*/
public static KaptchaVo createKaptcha() throws Exception {
DefaultKaptcha defaultKaptcha = getDefaultKaptcha();
return defaultKaptcha(defaultKaptcha);
}
/**
* 创建验证码,并生成图片到指定位置,返回验证码值
* @param imgPath
* @return
* @throws Exception
*/
public static String createKaptcha(String imgPath) throws Exception {
DefaultKaptcha defaultKaptcha = getDefaultKaptcha();
return defaultKaptcha(defaultKaptcha, imgPath);
}
public static class KaptchaVo {
private String code;//验证码
private byte[] imgs;//字节数组
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public byte[] getImgs() {
return imgs;
}
public void setImgs(byte[] imgs) {
this.imgs = imgs;
}
}
public static void main(String[] args) throws Exception {
//传入图片文件地址,返回验证码值
// String imgPath = "D:/temp/2.jpg";
// KaptchaUtils.createKaptcha(imgPath);
//创建验证码,返回验证码值与字节数组,可将字节数组输出到前端
KaptchaVo vo = KaptchaUtils.createKaptcha();
System.out.println(vo.code);
System.out.println(vo.getImgs().length);
}
}
说明:
做过项目的人都知道,很多写过的可重复利用的代码块或有用的工具类没有怎么整理,当需要的时候,又得打开项目查找一翻,虽然功能开发不难,但是又得花时间成本去写去测试,这样的重复造轮子的事情太多次了;因此不如把轮子保留,供大家一起使用;
1.这个轮子可以有:需要使用的时候确实还不存在这个组件。
2.我需要的时候轮子不在:每一种技术或工具产生都有它的项目背景,当代码写在项目里的时候,我知道有这个东西,当换了一个项目或公司后,没有备份也没有记录,这个时候你不在了,又得花时间手打一遍;
3.我不知道是不是造轮子:大多数情况下初学者很难分清楚自己是不是在重复造轮子,事实上造轮子不是我目的。我的目的是完成工作任务,任务完成的速度越快越好,质量越高越好。而不是去判断自己在不在造轮子。
4.不想重复花时间造轮子:有时候还会碰到一些并不困难但是很占时间的东西,当然有现成的轮子是花时间最少的;
5.我就是想学习轮子:初学者的并不是在重复造轮子,而是学习后以提高为自己的知识与技能。
轮子有过测试,但难免有失误,如有错误处,还敬请指出;