如今很多的网站都验证码功能,加入验证码可以防止黑客利用恶意程序,在网站中进行频繁登录、注册等操作。默默的想起了12306网站的验证码,更新换代那么多次,还是防不住一些厂商的软件。通过学习,体验了一下验证码的制作过程。
1.新建ValidateCodeServlet的Servlet类,在该类的doPost()方法中实现生成验证码的功能(包含随机获取颜色的功能)
package com.lhg.codeservlet;
import java.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;
public class ValidateCodeServlet extends HttpServlet {
@Override
protected void doPost(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"); //设置响应正文的MIME类型为图片
int width =60, height =20;
/*创建一个位于缓存的图像,宽度为60,高度为20*/
BufferedImage image =new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g =image.getGraphics(); //获取用于处理图形上下文的对象,相当于画笔
Random random =new Random(); //创建生成随机数的对象
g.setColor(getRandomColor(200,250)); //设置画像的背景色
g.fillRect(0, 0, width, height); //画一个矩形,坐标(0,0),宽度为60,高度为20
g.setFont(new Font("Times New Roman",Font.PLAIN,18)); //设定字体格式
g.setColor(getRandomColor(160, 200));
for(int i = 0;i<100;i++){ //产生100条随机干扰线
int x = random.nextInt(width);
int y = random.nextInt(height);
int x1 = random.nextInt(12);
int y1 = random.nextInt(12);
g.drawLine(x, y, x+x1, y+y1); //在图形的坐标之间画干扰线
}
String strCode ="";
for(int i =0; i<4; i++){
String strNumber =String.valueOf(random.nextInt(10)); //设置每次随机的数0~10
strCode =strCode +strNumber; //拼接生成的验证码
//设置字体的颜色
g.setColor(new Color(15+random.nextInt(120),15+random.nextInt(120),15+random.nextInt(120)));
g.drawString(strNumber, 13 * i+6, 16); //将验证码一次画到图像上,坐标(x=13*i +6,y =16)
}
request.getSession().setAttribute("Code", strCode); //验证码放到session中
g.dispose();
ImageIO.write(image,"JPEG", response.getOutputStream()); //输出JEPG格式的图像
response.getOutputStream().flush(); //刷新输出流
response.getOutputStream().close(); //关闭输出流
}
/**
* 随机获取颜色
* @param fc
* @param bc
* @return
*/
public Color getRandomColor(int fc,int bc){
Random random = new Random();
Color randomColor =null;
if(fc>255){
fc=255;
}
if(bc>255){
bc=255;
}
//设置0~255之间的随机颜色值
int r=fc +random.nextInt(bc - fc);
int g=fc +random.nextInt(bc - fc);
int b=fc +random.nextInt(bc - fc);
randomColor = new Color(r,g,b);
return randomColor; //返回具有指定的RGB颜色
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
}
由于服务器端的Servlet生成的图像首先是存放在缓存中,为了使客户端获取最新的图像,避免通过缓存获取图像,
应该在Servlet中通过设置HTTP响应头来禁止客户端缓存页面。即下面几行代码:
<span style="font-size:18px;"> //禁止页面缓存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-control", "No-cache");
//设置过期的时间
response.setDateHeader("Expires", 0);</span>
在Servlet中,首先要设置响应正文的类型为image/jpeg,表示响应的是一个图片,然后通过java.awt包中操作图像的类来生成一个图像。
主要用到以下几个类:
java.awt.image.BufferedImage:创建该对象时,会在缓存中构造一个图像
java.awt.Graphics:该类的对象表示一个画笔,可以用它来画一些图形。
java.util.Random:该类的对象用于生成随机数。
2 .在JavaWeb项目中的index配置页面标签
<form action="index.jsp" method="post">
用户名: <input type="text" name="name"/><br>
验证码: <img name="img1" src ="validatecode"><br>
输入验证码:<input type="text" name="code"/><br>
<input type="submit" value="刷新">
</form>
在该页的<img>标签中,通过src属性来调用ValidateCodeServlet类生成验证码,这个需要在web.xml配置servlet。
3.web.xml中配置
<servlet>
<servlet-name>ValidateCodeServlet</servlet-name>
<servlet-class>com.lhg.codeservlet.ValidateCodeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ValidateCodeServlet</servlet-name>
<url-pattern>/validatecode</url-pattern>
</servlet-mapping>
通过学习验证码实现的过程,了解了这个应用性很高的知识,发现也不是很难。
主要就是画图形——>获取随机数——>拼接输出。有兴趣的可以下载下面的源码看看: