您的位置:首页 > Web前端 > JavaScript

给JSP页面添加验证码

2017-03-22 19:20 411 查看
前段时间学习Struts2做了个验证码的小例子,今天在火狐下查看遇到点问题,在这里记录一下。
制作图形验证码关键在于编写生成图形的Servlet

[java] view
plain copy

package com.petrochina.servlet;

import <a href="http://lib.csdn.net/base/javase" class='replace_word' title="Java SE知识库" target='_blank' style='color:#df3434; font-weight:bold;'>Java</a>.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.image.BufferedImage;

import java.io.IOException;

import java.util.Random;

import javax.imageio.ImageIO;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

public class AuthImg extends HttpServlet {

// 设置图形验证码中字符串的字体和大小

&
20000
nbsp; private Font myFont = new Font("Arial Black", Font.PLAIN, 16);

@Override

public void init() throws ServletException {

super.init();

}

// 生成随机颜色

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);

}

@Override

public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

// 阻止生成的页面内容被缓存,保证每次重新生成随机验证码

response.setHeader("Pragma", "No-cache");

response.setHeader("Cache-Control", "no-cache");

response.setDateHeader("Expires", 0);

response.setContentType("image/jpeg");

// 指定图形验证码图片的大小

int width = 100, height = 20;

// 生成一张新图片

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

// 在图片中绘制内容

Graphics g = image.getGraphics();

Random random = new Random();

g.setColor(getRandColor(200, 250));

g.fillRect(1, 1, width - 1, height - 1);

g.setColor(new Color(102, 102, 102));

g.drawRect(0, 0, width - 1, height - 1);

g.setFont(myFont);

// 随机生成线条,让图片看起来更加杂乱

g.setColor(getRandColor(160, 200));

for (int i = 0; i < 155; i++) {

int x = random.nextInt(width - 1);// 起点的x坐标

int y = random.nextInt(height - 1);// 起点的y坐标

int x1 = random.nextInt(6) + 1;// x轴偏移量

int y1 = random.nextInt(12) + 1;// y轴偏移量

g.drawLine(x, y, x + x1, y + y1);

}

// 随机生成线条,让图片看起来更加杂乱

for (int i = 0; i < 70; i++) {

int x = random.nextInt(width - 1);

int y = random.nextInt(height - 1);

int x1 = random.nextInt(12) + 1;

int y1 = random.nextInt(6) + 1;

g.drawLine(x, y, x - x1, y - y1);

}

// 该变量用来保存系统生成的随机字符串

String sRand = "";

for (int i = 0; i < 6; i++) {

// 取得一个随机字符

String tmp = getRandomChar();

sRand += tmp;

// 将系统生成的随机字符添加到图形验证码图片上

g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));

g.drawString(tmp, 15 * i + 10, 15);

}

// 取得用户Session

HttpSession session = request.getSession(true);

// 将系统生成的图形验证码添加

session.setAttribute("rand", sRand);

g.dispose();

// 输出图形验证码图片

ImageIO.write(image, "JPEG", response.getOutputStream());

}

// 随机生成一个字符

private String getRandomChar() {

int rand = (int) Math.round(Math.random() * 2);// 将0~2的小数四舍五入生成整数

long itmp = 0;

char ctmp = '/u0000';

// 根据rand的值来决定是生成一个大写字母、小写字母和数字

switch (rand) {

// 生成大写字母的情形

case 1:

itmp = Math.round(Math.random() * 25 + 65);

ctmp = (char) itmp;

return String.valueOf(ctmp);

// 生成小写字母

case 2:

itmp = Math.round(Math.random() * 25 + 97);

ctmp = (char) itmp;

return String.valueOf(ctmp);

// 生成数字

default:

itmp = Math.round(Math.random() * 9);

return String.valueOf(itmp);

}

}

}

在web.xml中添加Servlet配置

[xhtml] view
plain copy

<!-- 生成验证码 -->

<servlet>

<servlet-name>authImg</servlet-name>

<servlet-class>com.petrochina.servlet.AuthImg</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>authImg</servlet-name>

<url-pattern>/authImg</url-pattern>

</servlet-mapping>

注册页面regist.jsp

[xhtml] view
plain copy

<%@ 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>

<mce:script type="text/<a href="http://lib.csdn.net/base/javascript" class='replace_word' title="JavaScript知识库" target='_blank' style='color:#df3434; font-weight:bold;'>JavaScript</a>" src="js/<a href="http://lib.csdn.net/base/jquery" class='replace_word' title="jQuery知识库" target='_blank' style='color:#df3434; font-weight:bold;'>jQuery</a>.1.4.2.js" mce_src="js/jquery.1.4.2.js"></mce:script>

<mce:script type="text/javascript"><!--

//刷新验证码

function refresh()

{

document.getElementById("authImg").src="authImg?now="+new Date();//使用时间作为参数避免浏览器从缓存取图片

}

// --></mce:script>

</head>

<body>

<form action="registe.action" method="post" id="registe">

<table>

<caption><h2>用户注册</h2></caption>

<tr>

<td>用 户 名:</td><td><input type="text" name="username" id="username"/></td>

</tr>

<tr>

<td>密 码:</td><td><input type="text" name="password" id="password"/> </td>

</tr>

<tr>

<td>确认密码:</td><td><input type="text" name="chkpassword"/> </td>

</tr>

<tr>

<td>Email:</td><td><input type="text" name="email"/> </td>

</tr>

<tr>

<td>验证码:</td><td valign="bottom"><input type="text" name="vercode" size="10"/> <img alt="" src="authImg" mce_src="authImg" id="authImg" align="absmiddle"><a href="#" mce_href="#" onclick="refresh()"><span style="font-size:12px" mce_style="font-size:12px">刷新验证码</span></a></td>

</tr>

<tr>

<td colspan="2"><input type="submit" value="提交"/><input type="reset" value="重填"/></td>

</tr>

</table>

</form>

</body>

</html>

后台RegistAction

[java] view
plain copy

@Override

public String execute() throws Exception {

Map session = ActionContext.getContext().getSession();

String ver2 = (String) session.get("rand");

session.put("rand", null);

// 判断验证码是否正确

if (vercode.equals(ver2)) {

if (userManager.validName(username)) {

if (userManager.addUser(username, password, email) > 0)

return SUCCESS;

else

addActionError("注册失败,请重试!");

} else {

addActionError("该用户名已存在,请重新输入!");

}

} else {

addActionError("验证码不匹配,请重新输入");

}

return INPUT;

}

结果如下:



到这里就完成了。但是今天在FireFox3.6下使用firedebug调试时发现会再请求一次验证码,这样导致session中的验证码刷新之后和页面上的不一致,问题截图如下:



在关闭firedebug的情况下只请求一次验证码,在IE下也正常,寻思可能是firedebug的问题,但是在网上查找不到相关内容。折腾了半天发现鼠标展开GET authImg的URL时才会第二次请求验证码,所以明白是因为验证码图片没有缓存造成在firedebug调试窗口查看时需要再次请求的缘故。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java