JavaWeb项目中,如登陆等页面需要生成验证码。验证码的作用就不多说了,下面直接上代码吧。
/**
* 生成验证码
* @author Mmmmm
* 需要的包自己导入
*/
public class RandomValidateCode {
//放到session中的KEY 用于验证,验证码输入是否正确
public static final String RANDOMCODEKEY="RANDOMVALIDATECODEKEY";
//随机
private Random random = new Random();
//验证码中的字符串 随机产生的字符串
private String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//设置图片的宽、高、干扰线数量、产生的随机字符数量
private int width = 120;
private int height = 40;
private int lineSize = 60;
private int stringNum = 4;
/**
* 获取字体
* @return 字体
*/
private Font getFont(){
//font(字体,风格/样式,字号)
return new Font("Fixedsys",Font.CENTER_BASELINE,25);
}
/**
* 获取随机颜色
* @param fc 字体颜色
* @param bc 背景颜色
* @return 颜色
*/
private Color getRandColor(int fc,int bc){
//参数超过255的话,默认255
if(fc > 255) fc = 255;
if(bc > 255) bc = 255;
//设置RGB值
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);
}
/**
* 生成随机图片
* @param request
* @param response
*/
public void getRandCode(HttpServletRequest request,HttpServletResponse response){
HttpSession session = request.getSession();
//定义一个缓冲图片
//BufferedImage(宽、高、BufferedImage.TYPE_INT_RGB)
//BufferedImage.TYPE_INT_RGB表示一个图像,它具有合成整数像素的8位RGB颜色含量
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//Graphics 类是所有图形上下文的抽象基类,
//允许应用程序在组件(已经在各种设备上实现)以及闭屏图像上进行绘制。
//getGraphics() 返回Graphics2D 和 createGraphics()基本相同
Graphics g = image.getGraphics();
//填充矩形,设置边框,Rect矩形
g.fillRect(0, 2, width, height);
//设置字体
g.setFont(new Font("Times New Roman",Font.ROMAN_BASELINE,25));
//设置颜色
g.setColor(getRandColor(110, 133));
//绘制干扰线
for(int i = 0; i < lineSize ; i++){
drowLine(g);
}
//绘制随机字符串
String randomString = "";
for(int i = 0 ; i < stringNum ; i++){
randomString = drowString(g,randomString,i);
}
//将随机字符串存到Session中 用于验证
session.removeAttribute(RANDOMCODEKEY);
session.setAttribute(RANDOMCODEKEY, randomString);
//释放此图形上下文及它使用的所有系统资源
g.dispose();
//将内存中的图片通过流的形式输出到客户端
try {
ImageIO.write(image, "JPEG", response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 绘制字符
* @param g Graphics
* @param randomString 随机字符串
* @param i int
* @return
*/
public String drowString(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;
//translate(x,y)将图形上下文的原点平移到当前坐标系中的点(x,y)
g.translate(random.nextInt(7), random.nextInt(6));
//drawString(str,x,y)使用此图形上下文的当前字体颜色绘制由指定STRING 给定的文本,最左侧字符基于上下文坐标系的(x,y)位置
//str ---------- 要绘制的String
//x,y ---------- 字符的坐标
g.drawString(rand, 22*i, 25);
return randomString;
}
/**
* 绘制干扰线
* @param g
*/
public void drowLine(Graphics g){
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
int x2 = random.nextInt(13);
int y2 = random.nextInt(15);
x2+=x1;
y2+=y1;
//drawLine(x1,y1,x2,y2)是使用当前颜色,在点(x1,y1)和点(x2,y2)之间画一条线
g.drawLine(x1, y1, x2, y2);
}
/**
* 获取随机的字符
* @param num 位置
* @return 字符
*/
public String getRandomString(int num){
return String.valueOf(randString.charAt(num));
}
}
上面是生成验证码的模块,使用方法是调用getRandCode方法就行。
**注意**
在调用的时候最好设置一下响应类型等,防止浏览器读缓存。
如:
//设置响应类型,告诉浏览器输出的内容为图片
resp.setContentType("image/jpeg");
//设置响应头信息,告诉浏览器不缓存此内容
//如果不设置的话,刷新不改变图片
resp.setHeader("pragma", "no-cache");
resp.setHeader("cache-control", "no-cache");
//设置一个时间值属性的响应头信息
resp.setDateHeader("expires", 0);//expires缓存的响应头
//验证码生成的类RandomValidateCode
RandomValidateCode rc = new RandomValidateCode();
//调用方法
rc.getRandCode(request, response);
效果图: