话不多说直接上代码!
jsp中验证码源文件:
<a id="ptr" href="javascript:;"><img height="27px" alt="换一张" src="<%=request.getContextPath() %>/getVerifyCode" id="prtImg"/></a>
struts配置文件:
<!-- 验证码 --> <action name="getVerifyCode" class="verifyCodeAction" method="getVerifyCode" > <result type="stream"> <param name="contentType">image/jpeg</param> <param name="inputName">inputStream</param> </result> </action>
java代码:
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; /** * 类描述:验证码生成 * * @author ming.li * @time 2011-4-21 上午11:30:45 */ public class VerifyCodeAction extends ActionSupport { /** 版本号 */ private static final long serialVersionUID = 5090480110300205197L; /** 文件输入流 */ private ByteArrayInputStream inputStream; /** 随机数 */ private static final Random random = new Random(); /** MD5加密 */ private static final MD5 md5 = new MD5(); /** 文本类型 */ private static final String CONTENT_TYPE = "image/jpeg"; /** 画布宽度 */ private static int imgWidth = 60; /** 画布高度 */ private static int imgHeight = 20; /** 验证码位数 */ private static int imgCount = 4; /** * * 方法描述:获取验证码 * * @author ming.li * @time 2011-4-25 下午01:56:19 * * @return */ public String getVerifyCode() { try { this.inputStream = generateImage(); } catch (IOException e) { e.printStackTrace(); } return SUCCESS; } /** * * 方法描述:输出验证码图片 * * @author ming.li * @time 2011-5-30 下午01:44:04 * * @return */ public ByteArrayInputStream getInputStream() { return inputStream; } /** * * 方法描述:输入验证码文件到流中 * * @author ming.li * @time 2011-4-25 下午01:56:29 * * @return * @throws IOException */ private ByteArrayInputStream generateImage() throws IOException { HttpServletResponse response = ServletActionContext.getResponse(); HttpServletRequest request = ServletActionContext.getRequest(); response.setContentType(CONTENT_TYPE); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); // PrintWriter out = response.getWriter(); int width = imgWidth, height = imgHeight; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 获取图形上下文 Graphics g = image.getGraphics(); // 设定背景色 g.setColor(getRandColor(200, 250)); g.setColor(new Color(255, 255, 255)); g.fillRect(0, 0, width, height); // 设定字体 g.setFont(new Font("Times New Roman", Font.PLAIN, 18)); // 画边框 g.setColor(getRandColor(200, 250)); g.drawRect(0, 0, width - 1, height - 1); // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到 g.setColor(getRandColor(160, 200)); for (int i = 0; i < 10; i++) { int x = random.nextInt(width); int y = random.nextInt(height); int xl = random.nextInt(100); int yl = random.nextInt(12); g.drawLine(x, y, x + xl, y + yl); } // 取随机产生的认证码(4位数字) StringBuffer randSB = new StringBuffer(); for (int i = 0; i < imgCount; i++) { String rand = String.valueOf(random.nextInt(10)); randSB.append(rand); // 将认证码显示到图象中 g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110))); // 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成 g.drawString(rand, 13 * i + 6, 16); } // 将认证码存入SESSION String randMD5 = md5.getMD5ofStr(randSB.toString()); request.getSession().setAttribute(Constants.VERFIY_CODE, randMD5); // 图象生效 g.dispose(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ImageIO.write(image, "JPEG", bos); byte[] buf = bos.toByteArray(); return new ByteArrayInputStream(buf); } /** * * 方法描述:给定范围获得随机颜色 * * @author ming.li * @time 2011-4-25 下午01:56:55 * * @param fc * @param bc * @return */ private static Color getRandColor(int fc, int bc) { // Random random = new Random(); if (fc > 255) { fc = 255; } if (bc > 255) { bc = 255; } int r = fc + random.nextInt(bc - fc); int g = fc + random.nextInt(bc - fc); int b = fc + random.nextInt(bc - fc); return new Color(r, g, b); } }