验证码增加了应用的安全性,验证码也有各种各样,如数字字母组合、汉字、点击数字等,其本质就是后台生成的验证码与前端输入的进行校验,下面通过代码来看一下:
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
path="/validateCodeAction"
type="path/ValidateCodeAction"
scope="request"
parameter="mt"
unknown="false"
validate="false"
>
3.在jsp配置
用于传入验证码:
这样就可以在登录逻辑中判断验证码是否正确。当访问量过大时,验证码放在session对服务器的压力增加,影响服务器的性能;若放在cookie中,则不安全。综合考虑使用的缓存,将生成的验证码存放到缓存中,设置失效时间,这样既可以实现安全性也能减轻服务器的压力。