
package com.hoo.util; |
|
import java.awt.Color; |
import java.awt.Font; |
import java.awt.Graphics; |
import java.awt.image.BufferedImage; |
import java.util.Random; |
import javax.imageio.ImageIO; |
import javax.servlet.http.HttpServletRequest; |
import javax.servlet.http.HttpServletResponse; |
/** |
* <b>function:</b> 验证码生成工具类 |
* @project NetWorkService |
* @package com.hoo.util |
* @fileName ValidCodeUtils.java |
* @createDate 2010-8-3 下午03:05:50 |
* @author hoojo |
*/ |
@SuppressWarnings("unused") |
public class ValidCodeUtils { |
/********************************************************************* |
* 验证码宽度 |
*/ |
public static int WIDTH = 60; |
/*** |
* 验证码高度 |
*/ |
public static int HEIGHT = 20; |
/********************************************************************** |
* 验证码背景颜色COLOR_FC_BG 应当小于COLOR_BC_BG |
*/ |
public static int COLOR_FC_BG = 200; |
/*** |
* 验证码背景颜色COLOR_FC_BG 应当小于COLOR_BC_BG |
*/ |
public static int COLOR_BC_BG = 250; |
/********************************************************************** |
* 验证码背景干扰线颜色COLOR_FC_LINE 应当小于COLOR_BC_LINE |
*/ |
public static int COLOR_FC_LINE = 160; |
/*** |
* 验证码背景干扰线颜色COLOR_FC_LINE 应当小于COLOR_BC_LINE |
*/ |
public static int COLOR_BC_LINE = 200; |
/*************************************************************************** |
* 验证码颜色COLOR_FC_CODE 应当小于COLOR_BC_CODE |
*/ |
public static int COLOR_FC_CODE = 20; |
/*** |
* 验证码颜色COLOR_FC_CODE 应当小于COLOR_BC_CODE |
*/ |
public static int COLOR_BC_CODE = 170; |
/*************************************************************************** |
* 生成在指定范围内的颜色 |
* @param fc 范围fc color值 小于255 |
* @param bc 范围bc color值 小于255 |
* @return Color |
*/ |
private static Color getRandColor(int fc, int bc) { |
Random random = new Random(); |
if (fc < 0) |
fc = 0; |
if (bc < 0) |
bc = 1; |
if (fc > 255) |
fc = 255; |
if (bc > 255) |
bc = 255; |
if (bc == fc) |
bc += 10; |
int temp = 0; |
if (bc < fc) { |
temp = bc; |
bc = fc; |
fc = temp; |
} |
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); |
} |
/** |
* <b>function:</b> 生成图片方法 |
* @createDate 2010-8-3 下午03:06:22 |
* @author hoojo |
* @param request HttpServletRequest |
* @param response HttpServletResponse |
* @return boolean |
* @throws Exception |
*/ |
public static boolean getImage(HttpServletRequest request, HttpServletResponse response) throws Exception{ |
response.reset(); |
response.setContentType("image/jpeg"); |
// 设置页面不缓存 |
response.setHeader("Pragma", "No-cache"); |
response.setHeader("Cache-Control", "no-cache"); |
response.setDateHeader("Expires", 0); |
// 在内存中创建图象 |
BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); |
// 获取图形上下文 |
Graphics img = image.getGraphics(); |
// 生成随机类 |
Random random = new Random(); |
// 设定背景色 |
img.setColor(getRandColor(COLOR_FC_BG, COLOR_BC_BG)); |
img.fillRect(0, 0, WIDTH, HEIGHT); |
// 设定字体 |
img.setFont(new Font("Times New Roman", Font.PLAIN, 18)); |
// 画边框 |
// g.setColor(new Color()); |
// g.drawRect(0,0,width-1,height-1); |
// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到 |
img.setColor(getRandColor(COLOR_FC_LINE, COLOR_BC_LINE)); |
for (int i = 0; i < 155; i++) { |
int x = random.nextInt(WIDTH); |
int y = random.nextInt(HEIGHT); |
int xl = random.nextInt(12); |
int yl = random.nextInt(12); |
img.drawLine(x, y, x + xl, y + yl); |
} |
// 取随机产生的认证码(4位数字) |
String codeValue = ""; |
for (int i = 0; i < 4; i++) { |
//String rand = String.valueOf(random.nextInt(10)); |
String rand = getRandomChar(); |
codeValue = codeValue.concat(rand); |
img.setFont(getRandomFont());//随机字体 |
// 将认证码显示到图象中 |
img.setColor(getRandColor(COLOR_FC_CODE, COLOR_BC_CODE)); |
img.drawString(rand, 13 * i + 6, 16); |
} |
request.getSession().setAttribute("codeValue", codeValue); |
// 图象生效 |
img.dispose(); |
// 输出图象到页面 |
return ImageIO.write(image, "JPEG", response.getOutputStream()); |
} |
/** |
* 随机生成字符,含大写、小写、数字 |
* <b>function:</b> 功能 |
* @createDate 2010-8-23 上午10:33:55 |
* @author hoojo |
* @return |
*/ |
public static String getRandomChar() { |
int index = (int) Math.round(Math.random() * 2); |
String randChar = ""; |
switch (index) { |
case 0://大写字符 |
randChar = String.valueOf((char)Math.round(Math.random() * 25 + 65)); |
break; |
case 1://小写字符 |
randChar = String.valueOf((char)Math.round(Math.random() * 25 + 97)); |
break; |
default://数字 |
randChar = String.valueOf(Math.round(Math.random() * 9)); |
break; |
} |
return randChar; |
} |
/** |
* <b>function:</b> 随机生成字体、文字大小 |
* @createDate 2010-8-23 上午10:44:22 |
* @author hoojo |
* @return |
*/ |
public static Font getRandomFont() { |
String[] fonts = {"Georgia", "Verdana", "Arial", "Tahoma", "Time News Roman", "Courier New", "Arial Black", "Quantzite"}; |
int fontIndex = (int)Math.round(Math.random() * (fonts.length - 1)); |
int fontSize = (int) Math.round(Math.random() * 4 + 16); |
return new Font(fonts[fontIndex], Font.PLAIN, fontSize); |
} |
} |
其中验证码的值是保存在session中:request.getSession().setAttribute("codeValue", codeValue); |
比较用户输入的值和session中的codeValue是否相等即可; |
下面是jsp页面调用servlet:ValidCodeServlet.java |
ValidCodeServlet中调用了上面的ValidCodeUtils 验证码生成工具类 |
package com.hoo.servlet; |
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.hoo.util.ValidCodeUtils; |
@SuppressWarnings("serial") |
public class ValidCodeServlet extends HttpServlet { |
public void doGet(HttpServletRequest request, HttpServletResponse response) |
throws ServletException, IOException { |
try { |
ValidCodeUtils.getImage(request, response); |
} catch (Exception e) { |
e.printStackTrace(); |
} |
} |
public void doPost(HttpServletRequest request, HttpServletResponse response) |
throws ServletException, IOException { |
doGet(request, response); |
} |
} |
|
jsp页面调用servlet方法即可 |
|
js:reloadValidCode方法 |
function reloadValidCode(o) { |
o.src = "${pageContext.request.contextPath }/validCodeServlet?timed=" + new Date().getMilliseconds(); |
} |
这里的"timed=" + new Date().getMilliseconds();是需要防止IE缓存用的 |
html标签: |
<img src="${pageContext.request.contextPath }/validCodeServlet" title="看不清,点击刷新" onclick="reloadValidCode(this)"/> |
直接跟Servlet名称配置的url即可,和web.xml配置对应。主要调用路径${pageContext.request.contextPath }/validCodeServlet这样会带上根目录,比较保险。 |
web.xml中validCodeServlet配置 |
<servlet> |
<servlet-name>validCodeServlet</servlet-name> |
<servlet-class>com.hoo.servlet.ValidCodeServlet</servlet-class> |
</servlet> |
<servlet-mapping> |
<servlet-name>validCodeServlet</servlet-name> |
<url-pattern>/validCodeServlet</url-pattern> |
</servlet-mapping> |
import java.awt.Color; |
import java.awt.Font; |
import java.awt.Graphics; |
import java.awt.image.BufferedImage; |
import java.io.IOException; |
import java.util.Date; |
import java.util.Random; |
import javax.imageio.ImageIO; |
import javax.servlet.ServletException; |
import javax.servlet.annotation.WebServlet; |
import javax.servlet.http.HttpServlet; |
import javax.servlet.http.HttpServletRequest; |
import javax.servlet.http.HttpServletResponse; |
/** |
* Servlet implementation class ValidateCode |
*/ |
@WebServlet("/ValidateCode") |
public class ValidateCode extends HttpServlet { |
private static final long serialVersionUID = 1L; |
|
/** |
* @see HttpServlet#HttpServlet() |
*/ |
public ValidateCode() { |
super(); |
// TODO Auto-generated constructor stub |
} |
/** |
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) |
*/ |
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { |
|
// 设置页面不缓存 |
response.setHeader("Pragma", "No-cache"); |
response.setHeader("Cache-Control", "no-cache"); |
response.setDateHeader("Expires", 0); |
// 设置图片的长宽 |
int width = 62, height = 22; |
// ////// 创建内存图像 |
BufferedImage image = new BufferedImage(width, height, |
BufferedImage.TYPE_INT_RGB); |
// 获取图形上下文 |
Graphics g = image.createGraphics(); |
// 设定图像背景色(因为是做背景,所以偏淡) |
g.setColor(getRandColor(180, 250)); |
g.fillRect(0, 0, width, height); |
// 设置字体 |
g.setFont(new Font("Times New Roman", Font.PLAIN, 17)); |
// /////设置默认生成4个验证码 |
int length = 4; |
java.util.Random rand = new Random(); // 设置随机种子 |
/* |
* if (request.getParameter("length") != null) { try { length = |
* Integer.parseInt(request.getParameter("length")); }catch |
* (NumberFormatException e) {} } |
*/ |
// 设置备选验证码:包括"a-z"和数字"0-9" |
String base = "abcdefghijklmnopqrstuvwxyz0123456789"; |
int size = base.length(); |
StringBuffer str = new StringBuffer(); |
for (int i = 0; i < length; i++) { |
int start = rand.nextInt(size); |
String tmpStr = base.substring(start, start + 1); |
str.append(tmpStr); |
// 生成随机颜色(因为是做前景,所以偏深) |
g.setColor(getRandColor(10, 150)); |
// 将此字画到图片上 |
// g.drawString(str.toString(), 4, 17); |
g.drawString(tmpStr, 13 * i + 6 + rand.nextInt(5), 14 + rand |
.nextInt(6)); |
} |
// 将认证码存入session |
request.getSession().setAttribute("valiCode", str.toString()); |
// 图象生效 |
g.dispose(); |
// 输出图象到页面 |
ImageIO.write(image, "JPEG", response.getOutputStream()); |
} |
public void doPost(HttpServletRequest request, HttpServletResponse response) |
throws ServletException, IOException { |
this.doGet(request, response); |
} |
// 给定范围获得一个随机颜色 |
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); |
} |
} |



