思路就是在一个action里应用java的awt包里面的类绘制一个内存中的图片,然后产生随机数并将随机数写到图片上,然后把action的返回类型设为stream,把图片数据写入到输入流返回给浏览器。html可以通过img页面直接用src属性引用该action 1.register.jsp中有如下代码(部分代码,其余部分自己写):
2. creatidateAction.java代码 import java.io.*; import java.util.Map; import javax.imageio.ImageIO; import javax.imageio.stream.ImageOutputStream; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import java.awt.*; import java.awt.image.BufferedImage; //DefaultAction类继承了ActionSupport 并定义了session变量 public class creatidateAction extends ActionSupport { private ByteArrayInputStream inputStream; //产生四个0~9的随机数,放在一个字符串里 public String createRandomString() { String str = ""; for (int i = 0; i < 4; i++) { str += Integer.toString((new Double(Math.random() * 10)).intValue()); } return str; } //随机产生一个颜色 public Color createsRandomColor() { int r = (new Double(Math.random() * 256)).intValue(); int g = (new Double(Math.random() * 256)).intValue(); int b = (new Double(Math.random() * 256)).intValue(); return new Color(r, g, b); } //生成一个内存图片,将四个随机数写在图片上 public BufferedImage createImage(String str) { int width = 60; int height = 22; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 获取图形上下文 Graphics g = image.getGraphics(); // 设定背景色 g.setColor(Color.WHITE); g.fillRect(0, 0, width, height); //画边框 g.setColor(Color.black); g.drawRect(0, 0, width - 1, height - 1); // 将认证码显示到图象中 g.setFont(new Font("Atlantic Inline", Font.PLAIN, 18)); //使用随机颜色 g.setColor(this.createsRandomColor()); //将随机字符串的每个数字分别写到图片上 g.drawString(Character.toString(str.charAt(0)), 8, 17); g.drawString(Character.toString(str.charAt(1)), 20, 17); g.drawString(Character.toString(str.charAt(2)), 33, 17); g.drawString(Character.toString(str.charAt(3)), 45, 17); // 图象生效 g.dispose(); return image; } //将图片的以字节形式写到InputStream里 public ByteArrayInputStream createInputStream() throws Exception { //获取随机字符串 String str=this.createRandomString(); BufferedImage image = this.createImage(str); //将产生的字符串写入session,供校验时使用 ActionContext actionContext = ActionContext.getContext(); Map session = actionContext.getSession(); session.put("random", str); ByteArrayOutputStream output = new ByteArrayOutputStream(); ImageOutputStream imageOut = ImageIO.createImageOutputStream(output); ImageIO.write(image, "JPEG", imageOut); imageOut.close(); ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); output.close(); return input; } @Override public String execute() throws Exception { setInputStream(createInputStream()); return SUCCESS; } public ByteArrayInputStream getInputStream() { return inputStream; } public void setInputStream(ByteArrayInputStream inputStream) { this.inputStream = inputStream; } } 3.Struts.xml中的配置
image/jpeg inputStream 4.验证 在RegisterAction中添加验证 @Override public void validate() { ActionContext actionContext = ActionContext.getContext(); Map session = actionContext.getSession(); if (!session.get("random").equals(validate)) { this.addFieldError(validate, "验证码错误"); } } 在RegisterAction-validation.xml中验证添加如下信息:
true 验证码不能为空 备注:以上是本人参考别人的代码加上自己通过实践验证得来,也不是原创,希望能给大家提供一点帮助