验证码增加了应用的安全性,验证码也有各种各样,如数字字母组合、汉字、点击数字等,其本质就是后台生成的验证码与前端输入的进行校验,下面通过代码来看一下:
1.编写生成代码的action类
import org.apache.commons.lang.RandomStringUtils; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import javax.imageio.ImageIO; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.awt.*; import java.awt.image.BufferedImage; import java.util.Random; public class ValidateCodeAction extends BaseAction { public ActionForward getCode(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { if (logger.isDebugEnabled()) { logger.debug("进入到ValidateCodeAction.getCode()方法"); } try { //设置图片的长度和宽度 int width =55; int height = 20; //生成一个4位的数字字母随机组合 String codeStr = RandomStringUtils.random(4, true, true); //设置response response.setContentType("images/jpeg"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); //获取session HttpSession session = request.getSession(); //生成验证 ServletOutputStream out = response.getOutputStream(); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics graphics=image.getGraphics(); //设置背景颜色 graphics.setColor(getRandColor(200,250)); graphics.fillRect(0,0,width,height); //设置字体 Font font=new Font("Times New Roman", Font.BOLD, 22); graphics.setFont(font); //设置边框 graphics.setColor(Color.BLACK); graphics.drawRect(0,0,width-1,height-1); //设置干扰线 graphics.setColor(getRandColor(160,200)); Random random=new Random(); for (int i = 0; i < 155; i++) { int x2 = random.nextInt(width); int y2 = random.nextInt(height); int x3 = random.nextInt(12); int y3 = random.nextInt(12); graphics.drawLine(x2, y2, x2 + x3, y2 + y3); } //将验证码显示到图片中 graphics.setColor(new Color(20 + random.nextInt(110), 20 + random .nextInt(110), 20 + random.nextInt(110))); graphics.drawString(codeStr,4,16); logger.debug("生成的验证码:"+codeStr); //将验证码设置到session中 session.setAttribute("validateCode",codeStr); //使图片生效 graphics.dispose(); ImageIO.write((BufferedImage) image, "JPEG", out); out.flush(); out.close(); } catch (Exception e) { logger.debug("生成验证码错误:" + e.getMessage()); } return null; } private 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); } }
2.在struts的配置文件配置action
<action path="/validateCodeAction" type="path/ValidateCodeAction" scope="request" parameter="mt" unknown="false" validate="false" > </action>
3.在jsp配置
获取验证码:<img src="${pageContext.request.contextPath}/path/validateCodeAction.do?reqCode=getCode"> 用于传入验证码:<input type="text" name="checkCode"/>
这样就可以在登录逻辑中判断验证码是否正确。当访问量过大时,验证码放在session对服务器的压力增加,影响服务器的性能;若放在cookie中,则不安全。综合考虑使用的缓存,将生成的验证码存放到缓存中,设置失效时间,这样既可以实现安全性也能减轻服务器的压力。