使用技术:jsp和Servlet
流程:
画图片
缓存
画笔
画图片,保存到流中
宽度 高度
OutputStream
画字符串
画字符串的方法
字符串保存到流中
Random
final StringSEED=”0-9 A-Z a-z”
画干扰线
画干扰点
代码:
util包中:
生成图片的类:
/**
* 此类方法只管画图片,其他一律不管
*/
public class GeneratorRandImage {
// 指定图片的宽度和高度
private int width = 120;
private int height = 30;
private OutputStream out = null; // 不能进行实例化
// 定义随机生成器,产生随机数
private Random rand = new Random();
/**
* 构造方法,接收指定的流
*/
public GeneratorRandImage(OutputStream out) {
this.out = out;
}
/**
* 随机数产生方法
* @return
*/
public String getRandString(int num) {
String str = "";
// 定义一个字符串的种子,随机字符串从该种子里面拿
final String SEED = "0123456789ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz";
for (int i = 0; i < num; i ++){
char s = SEED.charAt(rand.nextInt(SEED.length())); // 索引
str += s;
}
return str;
}
/**
* 得到随机颜色
* @return
*/
public Color getRandColor() {
int red = rand.nextInt(256);
int green = rand.nextInt(256);
int blue = rand.nextInt(256);
return new Color(red, green, blue);
}
/**
* 获得随机图片
*/
public StringgetRandImage() {
// 设置缓存,用来保存图片
BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 获得画笔
Graphics g = bufImg.getGraphics();
// 设置背景为白色
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
// 设置边框
g.setColor(Color.BLACK);
g.drawRect(0, 0, width - 1, height - 1);
// 设置字体
g.setFont(new Font("楷体", Font.BOLD, 22));
// 画字符串
String strCode = getRandString(5);
for (int i = 0; i < strCode.length(); i ++) {
// 设置字体的颜色
g.setColor(getRandColor());
g.drawString(String.valueOf(strCode.charAt(i)),10 + 22 * i, 20);
}
// 画干扰线
for (int i = 0; i < 5; i++) {
// 设置干扰线的颜色
g.setColor(getRandColor());
// 设置直线的连点坐标
int x1 = rand.nextInt(width);
int y1 = rand.nextInt(height);
int x2 = rand.nextInt(width);
int y2 = rand.nextInt(height);
g.drawLine(x1, y1, x2, y2);
}
// 画干扰点
for (int i = 0; i < 20; i++) {
// 设置干扰点的颜色
g.setColor(getRandColor());
// 设置干扰点的x、y坐标
int x = rand.nextInt(width);
int y = rand.nextInt(height);
g.drawOval(x, y, 2, 2);
}
// 关闭画笔,显示效果
g.dispose();
// 把图片写入到流中
try {
ImageIO.write(bufImg, "jpeg", out);
} catch (IOException e) {
e.printStackTrace();
}
return strCode;
}
}
Action(Servlet一块):
产生验证码图片的Action:
public class GetRandImageAction extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
// 获取流,指定流给图片
OutputStream out = response.getOutputStream();
// 实例化GeneratorRandImage
GeneratorRandImage fr = new GeneratorRandImage(out);
// 调用产生图片的方法,同时产生验证码
String strCode = fr.getRandImage();
// 将产生的验证码进行绑定
request.getSession().setAttribute("code", strCode);
}
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
进行验证码验证的Action:
public class CheckCodeAction extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
// 获取用户输入的验证码
String strCode = request.getParameter("code");
// 获取绘画对象。从Session里面获取正确的验证码
String strCode1 = (String) request.getSession().getAttribute("code");
System.out.println("strCode:" + strCode);
System.out.println("strCode1:" + strCode1);
PrintWriter out = response.getWriter();
if (strCode.equalsIgnoreCase(strCode1)) {
out.println("OK");
} else {
out.println("NO");
}
}
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
注意:别忘了在web.xml文件中进行配置。
页面中:
<body>
<form action="doCheckCode"method="post">
请输入验证码:<input type="text"name="code"/>
<img alt="看不清,点击切换图片" src="doJpg"onclick="history.go(0)">
<input type="submit"value="提交">
</form>
</body>
实现效果: