浏览 9103 次
锁定老帖子 主题:动态验证码生成
精华帖 (0) :: 良好帖 (0) :: 新手帖 (4) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-04-19
现在网上有很多在用户登陆或注册的时候为了防止程序攻击,加入了动态验证的技术,一般是让用户输入随即生成的验证码来实现。下面是一个用Servlet生成动态验证码的一个实例,可以根据实际需要进行修改。
1,生成动态验证码的Servlet。 package com.xcu.web; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.xcu.comm.CM; import com.xcu.exception.ApplicationException; public class ValidateCodeServlet extends HttpServlet { /** * 序列化版本UID编号 */ private static final long serialVersionUID = -7080388860058814634L; /** 验证码图片的宽度 */ private int width = 60; /** 验证码图片的高度 */ private int height = 25; /** 验证码字符个数 */ private int codeCount = 4; // 字符间距 private int x = 0; // 字体高度 private int fontHeight; private int codeY; char[] codeSequence = { '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', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; /** * 初始化验证图片属性 */ public void init() throws ServletException { // 从web.xml中获取初始信息 // 宽度 String strWidth = this.getInitParameter("width"); System.out.println("--------验证码宽度:"+strWidth); // 高度 String strHeight = this.getInitParameter("height"); System.out.println("--------验证码宽度:"+strHeight); // 字符个数 String strCodeCount = this.getInitParameter("codeCount"); System.out.println("--------验证码宽度:"+strCodeCount); // 将配置的信息转换成数值 try { if (strWidth != null && strWidth.length() != 0) { width = Integer.parseInt(strWidth); } if (strHeight != null && strHeight.length() != 0) { height = Integer.parseInt(strHeight); } if (strCodeCount != null && strCodeCount.length() != 0) { codeCount = Integer.parseInt(strCodeCount); } } catch (NumberFormatException e) { // e.printStackTrace(); throw new ApplicationException("web.xml中配置的验证码生成参数有误,请检查!", e); } x = width / (codeCount + 1); fontHeight = height - 2; codeY = height - 4; } protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException { // 定义图像buffer BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = buffImg.createGraphics(); // 创建一个随机数生成器类 Random random = new Random(); // 将图像填充为白色 g.setColor(Color.WHITE); g.fillRect(0, 0, width, height); // 创建字体,字体的大小应该根据图片的高度来定。 Font font = new Font("Fixedsys", Font.PLAIN | Font.BOLD, fontHeight); // 设置字体。 g.setFont(font); // 画边框。 g.setColor(Color.BLACK); g.drawRect(0, 0, width - 1, height - 1); // 随机产生160条干扰线,使图象中的认证码不易被其它程序探测到。 g.setColor(Color.pink); for (int i = 0; i < 160; 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); } // randomCode用于保存随机产生的验证码,以便用户登录后进行验证。 StringBuffer randomCode = new StringBuffer(); int red = 0, green = 0, blue = 0; // 随机产生codeCount数字的验证码。 for (int i = 0; i < codeCount; i++) { // 得到随机产生的验证码数字。 String strRand = String.valueOf(codeSequence[random.nextInt(36)]); // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。 red = random.nextInt(255); green = random.nextInt(255); blue = random.nextInt(255); // 用随机产生的颜色将验证码绘制到图像中。 g.setColor(new Color(red, green, blue)); g.drawString(strRand, (i + 1) * x - 6, codeY); // 将产生的四个随机数组合在一起。 randomCode.append(strRand); } // 将四位数字的验证码保存到Session中。 HttpSession session = req.getSession(); session.setAttribute(CM.VALIDATE_KEY, randomCode.toString()); // 禁止图像缓存。 resp.setHeader("Pragma", "no-cache"); resp.setHeader("Cache-Control", "no-cache"); resp.setDateHeader("Expires", 0); // 设置响应的类型格式为图片格式 resp.setContentType("image/jpeg"); // 将图像输出到Servlet输出流中。 ServletOutputStream sos = resp.getOutputStream(); ImageIO.write(buffImg, "jpeg", sos); sos.close(); } }
2,用户登录验证的Servlet package com.xcu.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.xcu.comm.CM; import com.xcu.dao.UserDao; import com.xcu.domain.Users; public class LoginCheckServlet extends HttpServlet { private static final long serialVersionUID = 4621074605453201722L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.sendRedirect("noright.jsp"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String userName = request.getParameter("userName"); String userPSD = request.getParameter("password"); String validateCode = request.getParameter("validateCode"); Users user = new Users(); if(userName != null && userName.length()>0 ){ user.setName(userName); } if(userPSD != null && userPSD.length()>0 ){ user.setPsd(userPSD); } String validateCodeInSession = (String) request.getSession() .getAttribute(CM.VALIDATE_KEY); request.getSession().removeAttribute(CM.VALIDATE_KEY); if (validateCodeInSession == null || validateCode == null || !validateCode.equalsIgnoreCase(validateCodeInSession)) { request.getSession().setAttribute(CM.ERR_MSG, "验证码错误"); request.getSession().setAttribute("userName", userName); response.sendRedirect("login.jsp"); } else { // 调用后台业务层的方法进行用户名和密码的校验! UserDao ud = new UserDao(); if (ud.validateUser(user)) { user = ud.find(user); request.getSession().setAttribute("user", user); response.sendRedirect("main.jsp"); } else { request.getSession().setAttribute(CM.ERR_MSG, "用户名或者密码错误"); request.getSession().setAttribute("userName", userName); response.sendRedirect("login.jsp"); } } } }
3,实用验证码的的JSP 页面。 <form method="post" action="login.do" name="form1"> <TABLE cellSpacing=0 cellPadding=0 width=318 border=0> <TBODY> <TR> <TD align=left> <font face="黑体"><span class="content_black_bold">用户名</span> <input type="text" id="userName" name="userName" value="${userName }" style="WIDTH: 200px" maxLength="20" /> </font> </TD> </TR> <TR> <TD height=3> <font face="黑体"><img width="1" height="5" border="0" alt="" src="images/spacer.gif"></font> </TD> </TR> <TR> <TD align=left> <font face="黑体"><span class="content_black_bold">密 码</span> <INPUT style="WIDTH: 200px" type="password" maxLength=32 id="password" name="password" minlength="6" /> </font> </TD> </TR> <TR> <TD height=3> <font face="黑体"><img width="1" height="5" border="0" alt="" src="images/spacer.gif"></font> </TD> </TR> <TR> <TD align=left valign="middle"> <font face="黑体"><span class="content_black_bold">验证码</span> <INPUT style="WIDTH: 80px" type="text" maxLength=32 id="validateCode" name="validateCode" minlength="6" /> </font><img src="validatecode.jpg" name="validateCode"> <a href="javascript:newCode();">看不清?</a> </TD> </TR> <TR> <TD height=3> <font face="黑体"><img width="1" height="5" border="0" alt="" src="images/spacer.gif"></font> </TD> </TR> <TR> <TD height=3> <font face="黑体"><img width="1" height="5" border="0" alt="" src="images/spacer.gif"></font> </TD> </TR> <TR> <TD noWrap align=right> <font face="黑体"><span style="padding-right: 20px;"><input type="submit" value="登 录" onclick="return check();"></span></font> </TD> </TR> </TBODY> </TABLE> </form>
4,Web.xml中对生成验证码Servlet的配置映射。 <servlet> <servlet-name>ValidateCodeServlet</servlet-name> <servlet-class>com.xcu.web.ValidateCodeServlet</servlet-class> <init-param> <param-name>width</param-name> <param-value>60</param-value> </init-param> <init-param> <param-name>height</param-name> <param-value>20</param-value> </init-param> <init-param> <param-name>codeCount</param-name> <param-value>4</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>ValidateCodeServlet</servlet-name> <url-pattern>/validatecode.jpg</url-pattern> </servlet-mapping>
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |