总体流程:
html页面发送生成验证码请求,java服务端生成对应的验证吗并回写到页面,点击验证码或者刷新页面及页面报错情况下,验证码都要刷新。
html端:
<img id="imageCode" alt="验证码" src="image_getImgCode.do"
style="margin-left:20px;height:36px;cursor: pointer;" />
$(function(){
//为图片绑定单击事件
$('#imageCode').click(function(){
//设置src属性为action的参数为当前时间,保证验证码点击之后可以变换
$(this).attr('src', 'image_getImgCode.do?dt=' + new Date().getTime());
});
});
struts.xml:
<action name="image_*" class="imageDemoAction" method="{1}"></action>
spring配置文件:
<bean id="imageDemoAction" class="com.infohold.businessyun.action.ImageDemoAction" scope="prototype"> </bean>
action:
public class ImageDemoAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private Logger logger = Logger.getLogger(ImageDemoAction.class);
//stream result只能输出InputStream类型
private InputStream imageStream;
public InputStream getImageStream() {
return imageStream;
}
public void setImageStream(InputStream imageStream) {
this.imageStream = imageStream;
}
public void getImgCode() throws IOException{
HttpServletResponse response = ServletActionContext.getResponse();
HttpServletRequest request = ServletActionContext.getRequest();
//生成验证码
Map<String, BufferedImage> map = ImageUtil.createImage();
String key = map.keySet().iterator().next();
HttpSession session = request.getSession();
session.removeAttribute("key");
session.setAttribute("key", key);
BufferedImage image = map.get(key);
try{
imageStream = ImageUtil.getInputStream(image);
OutputStream outputStream = response.getOutputStream();
ImageIO.write(image, "jpeg", outputStream);
outputStream.close();
}catch(IOException e){
logger.error("生成验证码失败:"+e.getMessage());
e.printStackTrace();
}
}
}
工具类:
/**
* 简单验证码生成工具
* ImageUtil, 用于生成验证码
* createImage方法返回一个Map类型,Map 的key是所生产的验证码的字符串,
* Map的value是所生产的BufferImage类型的验证码;
* getInputStream方法将 BufferImage转成InputStream类型;
* @author jiqing
*/
public class ImageUtil {
private static final char[] chars = {'0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
private static final int SIZE = 4; //字符数
private static final int LINES = 12; //干扰线数量
private static final int WIDTH = 130; //生成的验证码图片的宽度
private static final int HEIGHT = 60; //生成的验证码图片的长度
private static final int FONT_SIZE = 40; //字体大小
public static Map<String, BufferedImage> createImage(){
//用户保存字符串
StringBuffer sb = new StringBuffer();
//BufferImage类型的验证码
BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
//获得画笔
Graphics g = image.getGraphics();
g.setColor(Color.LIGHT_GRAY); //设置背景色
g.fillRect(0, 0, WIDTH, HEIGHT);//将背景色填充到图片中
Random ran = new Random(); //获得一个Random对象
//画字符
for(int i=1; i<=SIZE; i++){
int r = ran.nextInt(chars.length); //得到一个随机的下标, chars 是保存着若干字符的char字符
g.setColor(getRandomColor()); //得到一个随机的颜色
g.setFont(new Font(null, Font.BOLD+Font.ITALIC, FONT_SIZE)); //设置字体大小
g.drawString(chars[r]+"", (i-1)*WIDTH/SIZE, (int)(HEIGHT*0.7)); //画字符
sb.append(chars[r]);
}
//画干扰线
for(int i=1; i<=LINES; i++){
g.setColor(getRandomColor()); //同样,干扰线也是用随机的颜色
g.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT),
ran.nextInt(WIDTH), ran.nextInt(HEIGHT));//随机设置干扰线的方向
}
//将图片中的字符串保存为Map对象的key,BufferedImage保存为value
Map<String, BufferedImage> map = new HashMap<String, BufferedImage>();
map.put(sb.toString(), image);
return map;
}
/**
* 获得一个随机的颜色 返回 Color对象
* @return
*/
private static Color getRandomColor() {
Random ran = new Random();
Color color = new Color(ran.nextInt(256), ran.nextInt(256), ran.nextInt(256));
return color;
}
/**
* 将 BufferImage转成InputStream类型
* @param image
* @return
* @throws IOException
*/
public static InputStream getInputStream(BufferedImage image) throws IOException{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
encoder.encode(image);
byte[] imageBts = bos.toByteArray();
InputStream in = new ByteArrayInputStream(imageBts);
return in;
}
}