<1>画验证码核心类ValidateCodeAction
package com.tarena.common.action; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.Random; import javax.imageio.ImageIO; import javax.imageio.stream.ImageOutputStream; import com.opensymphony.xwork2.ActionContext; /** * 网页中验证码的实现 * @author JimmyZhang * @since 2012.5.10 * */ public class ValidateCodeAction { private ByteArrayInputStream inputStream; //默认的执行方法 public String execute() throws Exception{ Random r = new Random(); //BufferedImage相当与缓存在内存中的图像 BufferedImage image = new BufferedImage(60,//绘图区域的长度 20,//绘图区域的高度 BufferedImage.TYPE_INT_RGB); //获取绘图工具Graphiscs Graphics g = image.getGraphics(); //设置绘图颜色 g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255))); //从原点(0,0)填充绘图区域 g.fillRect(0, 0, 60, 20); //生成一个随机的字符串(5位数字) String number = String.valueOf(r.nextInt(99999)); //将number绘制在image中 g.setColor(new Color(0,0,0)); g.drawString(number, 5, 15); //将number保存在Session中 ActionContext ac = ActionContext.getContext(); ac.getSession().put("vcode", number); //画干扰线 for(int i=0; i<3;i++){ drawLine(g,r); } //写入到字节输出流中 ByteArrayOutputStream output = new ByteArrayOutputStream(); ImageOutputStream imageOutput = ImageIO.createImageOutputStream(output); //将图像image写入到imageOutput中 ImageIO.write(image, "jpeg", imageOutput); //根据output构建inputStream inputStream = new ByteArrayInputStream( output.toByteArray()); //对象之间的转换--image-->ByteArrayOutStream-->ByteArrayInputStream return "success"; } //辅助方法,用于绘制一条干扰线 private void drawLine(Graphics g,Random r){ g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255))); //drawLine(x1,y1,x2,y2) g.drawLine( r.nextInt(60), r.nextInt(20), r.nextInt(60), r.nextInt(20)); } public ByteArrayInputStream getInputStream() { return inputStream; } public void setInputStream(ByteArrayInputStream inputStream) { this.inputStream = inputStream; } }
<2>Struts2.0注册RegisterAction中验证码的逻辑实现
package com.tarena.dang.user.action; import java.io.*; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionContext; import com.tarena.dang.domain.User; import com.tarena.dang.user.service.UserService; import com.tarena.dang.user.service.UserServiceImpl; /** * 注册页面的Action控制器业务实现 * @author JimmyZhang * */ public class RegisterAction { private UserService userService; //使用实体对象简化与表单元素对应关系 private User user; private String vcode; //定义与文件域upload赌赢的属性 private File upload;//上传文件 private String uploadFileName;//上传文件的文件名 private String uploadContentType;//上传文件类型 public String getVcode() { return vcode; } public void setVcode(String vcode) { this.vcode = vcode; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public RegisterAction(){ userService = new UserServiceImpl(); System.out.println("【RegisterAction】调用默认无参构造方法"); } public String execute() throws Exception{ //判断用户输入的验证与session中是否一直一致 ActionContext ac = ActionContext.getContext(); String session_vocode = (String)ac.getSession().get("vcode"); if(!vcode.equals(session_vocode)){ ac.put("vcode_info", "<img src='/dang/images/wrong.gif'/>验证码不匹配"); return "input"; } boolean isSuccess = userService.register(user); if(isSuccess){ //上传头像,File upload-->/images/user/userName.jpg //得到服务器端的物理路径 String path = ServletActionContext .getServletContext().getRealPath("/images/user/"+user.getUserName()+".jpg"); //创建服务器端文件的File对象 File dest = new File(path); //upload-->dest InputStream fis = new FileInputStream(upload); OutputStream fos = new FileOutputStream(dest); byte[] b = new byte[1024]; int n; while((n=fis.read(b,0,b.length))!=-1){ fos.write(b,0,n); } fos.close(); fis.close(); //注册成功 ac.put("user", user); return "ok"; }else{ return "input"; } } public File getUpload() { return upload; } public void setUpload(File upload) { this.upload = upload; } public String getUploadFileName() { return uploadFileName; } public void setUploadFileName(String uploadFileName) { this.uploadFileName = uploadFileName; } public String getUploadContentType() { return uploadContentType; } public void setUploadContentType(String uploadContentType) { this.uploadContentType = uploadContentType; } }
<3>测试验证码效果的jsp页面
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>用户注册</title> <link type="text/css" rel="stylesheet" href="/dang/css/user.css"/> <script charset="gbk" type="text/javascript" src="/dang/js/jquery-1.4.1.js"></script> <script charset="gbk" type="text/javascript" src="/dang/js/jquery.validate.js"></script> <script type="text/javascript"> //跟换验证码 function changVcode(){ //获取图像对象的元素对象 var idVcode = document.getElementById("idVcode"); //改变其属性 idVcode.src="/dang/vcode.action?d=" +new Date().getTime(); } </script> <script type="text/javascript"> $(function(){ //表单验证 $('#registerForm').validate({ rules:{ 'user.userName':{required:true}, 'user.nickname':{required:true,minlength:4,maxlength:20}, 'user.userPassword':{required:true,minlength:6,maxlength:20}, passwordAgain:{required:true,equalTo:'#txtPassword'}, 'user.email':{required:true,email:true}, vcode:{required:true} }, messages:{ 'user.userName':{required:"<img src='/dang/images/wrong.gif'/>用户名不能为空"}, 'user.nickname':{required:"<img src='/dang/images/wrong.gif'/>昵称不能为空", minlength:"<img src='/dang/images/wrong.gif'/>昵称的长度不能少于{0}位", maxlength:"<img src='/dang/images/wrong.gif'/>昵称的长度不能大于{0}位"}, 'user.userPassword':{required:"<img src='/dang/images/wrong.gif'/>密码不能为空", minlength:"<img src='/dang/images/wrong.gif'/>密码的长度不能少于{0}位", maxlength:"<img src='/dang/images/wrong.gif'/>密码的长度不能大于{0}位"}, passwordAgain:{required:"<img src='/dang/images/wrong.gif'/>确认密码不能为空", equalTo:"<img src='/dang/images/wrong.gif'/>确认密码和密码不相等"}, 'user.email':{required:"<img src='/dang/images/wrong.gif'/>Email地址不能为空", email:"<img src='/dang/images/wrong.gif'/>Email地址格式无效"}, vcode:{required:"<img src='/dang/images/wrong.gif'/>验证码不能为空"} }, errorPlacement:function(error,element){ error.appendTo( element.parent().next().find("span").eq(0)); } }); }); </script> </head> <body> <div class="container"> <!-- header begin --> <div class="header"> <a href="http://localhost:8080/dang"> <img border="0" alt="我的当当网" src="/dang/images/logo_20110808.png"/> </a> </div> <!-- header end --> <!-- middle begin --> <div class="middle register"> <h1>欢迎注册我的当当网!</h1> <div> <span class="error"></span> <form id="registerForm" name="registerForm" enctype="multipart/form-data" action="/dang/user/register.action" method="post"> <table> <tr><td class="c1">请输入您的用户名:</td> <td class="c2"> <input id="userName" name="user.userName"/> </td> <td class="c3"> <span id="userNameInfo" class="info"></span> </td></tr> <!-- 文件域开始 --> <tr><td class="c1">上传头像</td> <td class="c2"><input type="file" name="upload"></td> </tr> <tr><td class="c3"></td></tr> <!-- 文件域开始 --> <tr><td class="c1">设置您的昵称:</td> <td class="c2"><input name="user.nickname"/></td> <td class="c3"> <span class="tip">您的昵称由英文字母、数字、中文组成,长度为4-20个字符<br/></span> </td></tr> <tr><td class="c1">设置密码:</td> <td class="c2"><input id="txtPassword" type="password" name="user.userPassword"/></td> <td class="c3"><span class="tip">你的密码由英文字母、数字组成,长度6-20位<br/></span></td></tr> <tr><td class="c1">再次输入您设置的密码:</td> <td class="c2"><input type="password" name="passwordAgain"/></td> <td class="c3"> <span class="tip"></span> </td></tr> <tr><td class="c1">请填写您的Email地址:</td> <td class="c2"><input name="user.email"/></td> <td class="c3"><span class="tip"></span></td></tr> <tr><td class="c1">验证码:</td> <td class="c2"> <input name="vcode" style="width:96px;"/> <img id="idVcode" alt="验证码" src="/dang/vcode.action" align="bottom" style="height:20px;"/> </td> <td class="c3"> <span class="tip">请输入图片中文字 <a id="idRefresh" href="#" onclick="changVcode()">看不清,再换一张</a> <br/> <font color="red">${vcode_info}</font> </span> </td></tr> </table> <div> <input id="btn_register" type="image" class="btn_register" alt="" src="/dang/images/register.jpg"/> </div> </form> </div> </div> <!-- middle end --> <!-- footer begin --> <div class="footer"> Copyright © dangdang v2.0, 2011-2012, All Rights Reserved | 京ICP证08000853号 北京达内科技有限公司 <br/> <img alt="" src="/dang/images/validate.gif"/> <img alt="" src="/dang/images/knetSealLogo.png"/> </div> <!-- footer end --> </div> </body> </html>
打完收工,可以直接将源码导入工程中测试,还等什么,实现一下