前段时间工作时用java代码总结修改了一个验证码生成的工具类,在此做以下总结:
1.验证码生成工具类:
生成图片使用java.awt.image软件包下的BufferedImage类, Image是一个抽象类,而BufferedImage是Image的实现。Image和BufferedImage的主要作用就是将一副图片加载到内存中。
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Random;
/**
* @author : ShiLei
* @time :2018年1月3日 上午11:20:44
* @introduction : java生成 验证码 工具类
*/
public class CheckCodeImageUtil {
// 随机生成的字符串的长度
private int stringLength = 4;
// 图片的背景色
private Color bgColor = new Color(240, 240, 180);
// 干扰线的宽度
private final int lineWidth = 2;
// 干扰线的数量
private final int lineNumber = 100;
// 字体大小
private int fontSize = 20;
// 随机字符串的字体
private Font font = new Font("Arial", Font.BOLD, fontSize);
// 随机生成的字符串
private String randString="";
// 图片宽度
private int width = 90;
// 图片高度
private int height = 25;
/**
* 产生随机前景色,这里的色调基准为深色调
* @return 随机颜色
*/
private Color createRandColor() {
Random random = new Random();
// 红色
int red = random.nextInt(100);
// 绿色
int green = random.nextInt(100);
// 蓝色
int blue = random.nextInt(100);
return new Color(red, green, blue);
}
/**
* 根据预定义的字符长度,自定义规则生成随机字符串
* @return 一个随机字符串
*/
private void createRandString() {
StringBuffer sb = new StringBuffer();
Random random = new Random();
// ASCII码 48~57为0到9十个阿拉伯数字
// ASCII码 65~90为26个大写英文字母
// ASCII码 97~122号为26个小写英文字母
for (int i = 0; i < this.stringLength; i++) {
// 默认全部生成数字,可自定义修改成字母及数字混合型
sb.append((char) (random.nextInt(10) + 48));
}
this.randString = sb.toString();
}
/**
* 获得随机字符串
* @return 随机字符串
*/
public String getRandString() {
return randString;
}
/**
* 生成图片
* @return BufferedImage
*/
public BufferedImage createImage() {
Random random = new Random();
// 图片为指定宽度和高度的RGB类型图片
BufferedImage image = new BufferedImage(this.width, this.height,
BufferedImage.TYPE_INT_BGR);
Graphics2D graphics = image.createGraphics();
// 设置矩形颜色
graphics.setColor(this.bgColor);
// 绘制矩形
graphics.fillRect(0, 0, this.width, this.height);
// 设置边框颜色
graphics.setColor(Color.GREEN);
// 绘制边框
graphics.drawRect(0, 0, this.width - 1, this.height - 1);
// 绘制干扰线
for (int i = 0; i < this.lineNumber; i++) {
// 设置线条的颜色
graphics.setColor(this.createRandColor());
int x = random.nextInt(width - lineWidth - 1) + 1;
int y = random.nextInt(height - lineWidth - 1) + 1;
int xl = random.nextInt(lineWidth);
int yl = random.nextInt(lineWidth);
graphics.drawLine(x, y, x + xl, y + yl);
}
// 产生随机字符串
this.createRandString();
graphics.setFont(this.font);
// 将字符数组转化成字符数组
char[] chars = this.getRandString().toCharArray();
for (int i = 0; i < chars.length; i++) {
graphics.setColor(this.createRandColor());
String letter = new Character(chars[i]).toString();
// 这里调整字符的间距和高度,水平偏差为10,高度偏差为15
graphics.drawString(letter, (random.nextInt(5)
+ (this.fontSize - 2) * (i + 1) - 5),
(random.nextInt(5)) + 18);
}
// 图片生效
graphics.dispose();
return image;
}
}
2. 将图片验证码从内存输出到页面上
@RequestMapping("createCheckCode")
@ResponseBody
public void createCheckCode(HttpServletRequest request,HttpServletResponse response) {
// 设置页面不缓存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/gif");
// 生成的图片
CheckCodeImageUtil img = new CheckCodeImageUtil();
BufferedImage image = img.createImage();
//可将生成的验证码存入缓存 同时设置过期时间,用于验证码校验
String checkCode = img.getRandString();
OutputStream out = null;
try {
// Servlet输出流
out = response.getOutputStream();
// 将图片写入到输出流中去
ImageIO.write(image, "JPG", out);
// 强制刷新
out.flush();
// 关闭输出流
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
3. 页面引用 并点击实时刷新
<img id="img" title="CheckCode" οnclick="flushCheckCode()" style="height:32px;">
<script type="text/javascript">
var url='/sl_api/slController/createCheckCode.do';
$(function(){
$('#img').attr('src',url);
})
function flushCheckCode() {
$('#img').attr('src', url+'?' + Math.random());
}
</script>
注意:
由于浏览器会对同一URL的图像进行缓存,以减少服务器端的请求次数,提高浏览性能. 利用附加一个随机数,来避免客户端浏览器使用缓存.让每次点击刷新验证码的时候请求的URL路径都不同,这样客户端会以为是新的页面,从而会向服务器发起请求以实现每次点击都会刷新验证码的效果.