验证码代码取之网络,但是网络上代码都不完整,因此修改后发上来大家分享。
先看看效果:
一、生成图形验证码的Action
package com.wjt276.co.web.actions;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import com.wjt276.co.managers.ValidateImageManager;
@SuppressWarnings("serial")
public class ValidateImgAction extends BaseAction {
/**
* 用于保存已经生成的图形验证码输入流对象,以便在前台显示图形
*/
private ByteArrayInputStream inputStream;
/**
* 图形验证码创建接口
*/
private ValidateImageManager validateImageManager;
/**
* 图形验证码图形的宽度
*/
private int width;
/**
* 图形验证码图形的高度
*/
private int height;
/**
* 图形验证码图形上字体大小
*/
private int fontSize;
/**
* 生成验证码的位数
*/
private int codeLength;
/**
* 图形验证码的图形类型
*/
private String contentType;
public String execute() throws Exception{
//保存已经生成好的验证码
Key.validateCode = createInputStream(ValidateImageManager.Disturb_Type_Complex);
return SUCCESS;
}
/**
* 在Action层创建图形验证码,并将创建好的图形字节流保存到inputStream对象中,并返回验证码
* @param disturbType 绘制干扰线的类型;<br/>
* 0:不绘制干扰线;<br/>
* 1:绘制单一色调的干扰线;<br/>
* 2:绘制复杂的干扰线
* @return 返回已经生成好的验证码字符
* @throws IOException
*/
protected String createInputStream(int disturbType) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String validateCode = null;
validateCode = validateImageManager.createValidateCode(disturbType,
this.getFontSize(),
bos,
this.getWidth(),
this.getHeight(),
getText("System.validateCode",ValidateImageManager.Default_ValidateCode),
this.getCodeLength());
inputStream = new ByteArrayInputStream(bos.toByteArray());
bos.close();
return validateCode;
}
//------------以下为getXXX/setXXX方法-------------------------
public ByteArrayInputStream getInputStream() {
return inputStream;
}
public void setInputStream(ByteArrayInputStream inputStream) {
this.inputStream = inputStream;
}
public ValidateImageManager getValidateImageManager() {
return validateImageManager;
}
public void setValidateImageManager(ValidateImageManager validateImageManager) {
this.validateImageManager = validateImageManager;
}
public String getContentType() {
if(null == this.contentType || "".equals(this.contentType.trim())){
return Key.DEFAULT_VALIDATEIMG_CONTENT_TYPE;
}
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public int getWidth() {
if(this.width < Key.DEFAULT_VALIDATEIMG_WIDTH){
return Key.DEFAULT_VALIDATEIMG_WIDTH;
}
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
if(this.height < Key.DEFAULT_VALIDATEIMG_HEIGHT){
return Key.DEFAULT_VALIDATEIMG_HEIGHT;
}
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getFontSize() {
if(this.fontSize < Key.DEFAULT_VALIDATEIMG_FONT_SIZE){
return Key.DEFAULT_VALIDATEIMG_FONT_SIZE;
}
return fontSize;
}
public void setFontSize(int fontSize) {
this.fontSize = fontSize;
}
public int getCodeLength() {
if(this.codeLength < Key.DEFAULT_VALIDATEIMG_CODE_LENGTH){
return Key.DEFAULT_VALIDATEIMG_CODE_LENGTH;
}
return codeLength;
}
public void setCodeLength(int codeLength) {
this.codeLength = codeLength;
}
}
二、生成图形验证码的接口ValidateImageManager
package com.wjt276.co.managers;
import java.io.ByteArrayOutputStream;
public interface ValidateImageManager {
/**
* 默认验证字符串
*/
public static final String Default_ValidateCode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
/**
* 默认绘制干扰线的类型(不绘制干扰线)
*/
public static final int Disturb_Type_Default = 0;
/**
* 绘制单一色调的干扰线
*/
public static final int Disturb_Type_Simple = 1;
/**
* 绘制复杂的干扰线
*/
public static final int Disturb_Type_Complex = 2;
/**
* 生成验证图片并返回验证码
*
* @param disturbType 绘制干扰线的类型;<br/>
* 0:不绘制干扰线;<br/>
* 1:绘制单一色调的干扰线;<br/>
* 2:绘制复杂的干扰线
* @param fontSize 图形上验证码字体的大小
* @param bos 字节流,用于返回生成的图形验证码字节流,并显示于前台
* @param width 图形的宽度
* @param height 图形的高度
* @param validateCode 默认的验证码编码
* @param codeLength 验证码字符长度
* @return 返回生成好的验证码字符
*/
public abstract String createValidateCode(int disturbType, int fontSize,
ByteArrayOutputStream bos, int width, int height,
String validateCode, int codeLength);
}
一、生成图形验证码的实现ValidateImageManagerImpl
package com.wjt276.co.managers.impl;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import com.wjt276.co.managers.ValidateImageManager;
public class ValidateImageManagerImpl extends AbstractManager implements
ValidateImageManager {
/**
* 生成验证图片并返回验证码
*
* @param disturbType 绘制干扰线的类型;<br/>
* 0:不绘制干扰线;<br/>1:绘制单一色调的干扰线;<br/>2:绘制复杂的干扰线
* @param fontSize 图形上验证码字体的大小
* @param bos 字节流,用于返回生成的图形验证码字节流,并显示于前台
* @param width 图形的宽度
* @param height 图形的高度
* @param validateCode 默认的验证码编码
* @param codeLength 验证码字符长度
* @return 返回生成好的验证码字符
*/
public String createValidateCode(int disturbType,
int fontSize,
ByteArrayOutputStream bos,
int width,
int height,
String validateCode,
int codeLength) {
BufferedImage bImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = bImg.getGraphics();
Random random = new Random();
if (null == validateCode || validateCode.isEmpty()) {
validateCode = Default_ValidateCode;
}
if (fontSize >= height) {
fontSize = height - 1;
}
drawOutline(g, width, height);
switch (disturbType) {
case Disturb_Type_Simple:
drawSimpleDisturb(g, random, width, height);
break;
case Disturb_Type_Complex:
drawDisturb(g, random, width, height);
break;
default:
break;
}
String code = drawCode(g, random, validateCode, codeLength, width,
height, fontSize);
g.dispose();
try {
ImageOutputStream imOut = ImageIO.createImageOutputStream(bos);
ImageIO.write(bImg, "JPEG", imOut);
imOut.close();
} catch (IOException e) {
e.printStackTrace();
}
return code;
}
/**
* 绘制边框
*
* @param g
* @param width
* @param height
*/
private static void drawOutline(Graphics g, int width, int height) {
g.setColor(Color.white);
g.fillRect(0, 0, width, height);
g.setColor(Color.BLACK);
g.drawRect(0, 0, width - 1, height - 1);
}
/**
* 绘制比较复杂的干扰线
*
* @param g
* @param random
* @param width
* @param height
*/
private static void drawDisturb(Graphics g, Random random, int width,
int height) {
int x, y, x1, y1;
for (int i = 0; i < width; i++) {
x = random.nextInt(width);
y = random.nextInt(height);
x1 = random.nextInt(12);
y1 = random.nextInt(12);
g.setColor(getRandomColor(random, 120, 255));
g.drawLine(x, y, x + x1, y + y1);
g.fillArc(x, y, x1, y1, random.nextInt(360), random.nextInt(360));
}
}
/**
* 绘制简单的干扰线
*
* @param g
* @param random
* @param width
* @param height
*/
private static void drawSimpleDisturb(Graphics g, Random random, int width,
int height) {
g.setColor(getRandomColor(random, 160, 200));
for (int i = 0; i < 155; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x, y, x + xl, y + yl);
}
}
/**
* 取得随机颜色
*
* @param random
* @param pMin
* @param pMax
* @return
*/
private static Color getRandomColor(Random random, int pMin, int pMax) {
pMax = (Math.abs(pMax) > 255 ? 255 : Math.abs(pMax));
pMin = (Math.abs(pMin) > 255 ? 255 : Math.abs(pMin));
int r = pMin + random.nextInt(Math.abs(pMax - pMin));
int g = pMin + random.nextInt(Math.abs(pMax - pMin));
int b = pMin + random.nextInt(Math.abs(pMax - pMin));
return new Color(r, g, b);
}
/**
* 绘制验证码
*
* @param g
* @param random
* @param validateCode
* @param codeLength
* @param width
* @param height
* @param fontSize
* @return
*/
private static String drawCode(Graphics g, Random random,
String validateCode, int codeLength, int width, int height,
int fontSize) {
int validateCodeLength = validateCode.length();
Font font1 = new Font("Verdana", Font.BOLD, fontSize);
Font font2 = new Font("serif", Font.BOLD, fontSize);
StringBuffer sb = new StringBuffer();
int x, y;
for (int i = 0; i < codeLength; i++) {
x = (width / codeLength - 1) * i
+ random.nextInt(width / (codeLength * 2));
y = random.nextInt(height - fontSize) + fontSize;
sb.append(getRandomChar(validateCode, validateCodeLength, random));
g.setColor(getRandomColor(random, 70, 150));
if (sb.substring(i).getBytes().length > 1)
g.setFont(font2);
else
g.setFont(font1);
g.drawString(sb.substring(i), x, y);
}
return sb.toString();
}
/**
* 取得随机字符
*
* @param validateCode
* @param validateCodeLength
* @param random
* @return
*/
private static char getRandomChar(String validateCode,
int validateCodeLength, Random random) {
return validateCode.charAt(random.nextInt(validateCodeLength));
}
}