验证码
验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机和人的公共全自动程序。可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,
public class ImageServlet extends HttpServlet {
//设置图像的宽度
private int width=85;
//设置图像的高度
private int height=30;
//验证码使用的字符
private char[] charSeq="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".toCharArray();
//生成验证码字符的个数
private int count=4;
//定义字符的基线
private int codeX;
private int codeY;
public void init() throws ServletException {
//计算字符基线
codeX=width/(count+2);
codeY=height;
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//在缓冲区创建一个图像区域
BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//获取图像的绘图区域对象
Graphics g=image.getGraphics();
//设置图形的背景色
g.setColor(Color.white);
g.fillRect(0, 0, width, height);
//设置图形的边框
g.setColor(Color.black);
g.drawRect(0, 0, width-1, height-1);
Random random=new Random();
String str="";
for(int i=0;i<count;i++){
String rank=String.valueOf(charSeq[random.nextInt(charSeq.length)]);
System.out.println(rank);
str=str+rank;
//在图片上画字符数字
g.setColor(Color.blue);
//设置字体
g.setFont(new Font("宋体",Font.BOLD,30));
g.drawString(rank, codeX*(i+1), codeY);
}
//放置验证码到sesison中
request.getSession().setAttribute("keycode", str);
//增加干扰点
for(int i=0;i<155;i++){
g.setColor(Color.red);
g.drawOval(random.nextInt(width), random.nextInt(height), 0, 0);
}
//释放此图形的上下文以及它使用的所有系统资源。
g.dispose();
//设定网页的到期时间,一旦过期则必须到服务器上重新调用
response.setDateHeader("Expires",-1);
//Cache-Control指定请求和响应遵循的缓存机制 no-cache指示请求或响应消息不能缓存
response.setHeader("Cache-Control","no-cache");
//是用于设定禁止浏览器从本地机的缓存中调阅页面内容,设定后一旦离开网页就无法从Cache中再调出
response.setHeader("Pragma","no-cache");
//输出图像到响应对象的输入流中
ImageIO.write(image, "JPEG", response.getOutputStream());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
中文验证码
public class ImageServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//获取图像的绘图区域对象
g=image.getGraphics();
//设置背景颜色
g.setColor(Color.red);
//给指定图形区域填充
g.fillRect(0,0,width,height);
//设置图形的边框
g.setColor(Color.blue);
g.drawRect(0,0,width-1,height-1);
//随机从字符数组中获取随机数
Random random=new Random();
/**中文汉字区间 [\u4e00\u9fa5],随机获取4个中文字符
int start = '\u4E00 ';
int end = '\u9FA0 ';
String str = " ";
Random r = new Random();
for(int i=0; i <4; i++){
str += (char)(start+r.nextInt(end-start));
}
System.out.println(str);
*/
String base="\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u84bf\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c"
Graphics2D gg=(Graphics2D)g;
for(int i=0;i<4;i++){
//30*3.14/180代表是30度
//int degree=random.nextInt(30);//0-30°
int degree=random.nextInt()%30;//-30-30
gg.rotate(degree*Math.PI/180,codeX(i+1),codeY);//设置旋转的幅度
String ch=base.charAt(random.nextInt(base.length()))+"";
gg.setFont(new Font("宋体",Font.BOLD,20))
gg.drawString(ch,codeX*(i+1),codeY);
gg.rotate(-degree*Math.PI/180,codeX(i+1),codeY);
}
String str="";
for(int i=0;i<cout;i++){
String rand=String.valueof(charseq[random.nextInt[charseq.length]]);
str=str+rand;
//在图片上画字符数字
g.setColor(Color.blue);
g.setFont(new Font("宋体",Font.BOLD,20));
g.drawString(rand,codeX*(i+1),codeY);
}
//将验证码放置到session中
session=request.getSession();
session.setAttribute("checksession",str);
//增加干扰线
for(int i=0;i<5;i++){
g.setColor(Color.GREEN);
int x1=random.nextInt(width);
int y1=random.nextInt(height);
int x2=random.nextInt(width);
int y2=random.nextInt(height);
g.drawLine(x1,y1,x2,y2);
}
//增加干扰点
for(int i=0;i<100;i++){
g.setColor(Color.red);
g.drawOval(random.nextInt(width),random.nextInt(height),0,0);
}
//释放图形的使用的区域
g.dispose();
//告诉游览器以什么读取文件
response.setContentType("image/jpeg");
//输出图像到响应对象的输出流中
ImageIO.write(image,"JPEG",response.getOutputStream())
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
在客户端要引用image的servlet,在javascript中使用随机数Math.random()或者时间戳,或者uuid防止缓存