zoukankan      html  css  js  c++  java
  • jsp实现验证码

    在web开发领域里面,验证码是一个比较常见的功能,而归根到底,验证码其实就是一组随机数,或者是一个随机算术

    一、基本知识

    1、为什么需要验证码?

    验证码,很多时候出现在注册页面或者登陆界面,在这些页面中有可能会出现恶意注册和暴力破解,这时候验证码可以有效防范这些攻击。所以,总的来说,验证码很多时候是为了防止不法分子对网站进行恶意的注册和攻击,是一种有效的拦截手段。

    2、验证码的工作原理

      首先,我们要明确一点就是,验证码实际是在服务器端产生的,因为如果在前端参数的话并不能有效拦截,因此很多时候,在拦截时我们都需要在服务器端进行相关操作,防止黑客绕过前端验证直接非法访问。

      验证码的工作原理其实方几个步骤:首先,服务端随机产生几个随机数或者随机算式,然后通过session对象将数据传输到客户端,客户端输入验证码,通过r表单将数据提交到服务器,服务器提取数据之后和产生的随机数字或者算式的结果对比,以此进行验证。

      当然,很多时候,简单的验证码很容易被图像识别软件破解,所以现在很多时候更流行短信验证等方式,但是,一下讨论的均是简单的数字图片验证。

    二、验证码的实现过程

    1、首先,验证码其实就是在服务端产生一张带有验证码数字或者算式的图片,所以,在这个过程要用到gui知识,具体请先看一下代码

    //1、验证码界面
    	//验证码的宽和高
    	int width = 70;
    	int height = 30;
    	/*
    	*图像缓冲对象(注意:在多次对某个对象操作时,为了提高效率,很多时候选择用缓冲对象来进行操作,
    	因为缓冲类的对象很多时候是可以即时改变对象的数据的)
    	*/
    	BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
    	//创建图像操作对象,用于操作验证码图片对象
    	Graphics2D g = bufferedImage.createGraphics();
    	//创建字体对象方便操作图像字体的属性
    	Font font = new Font("Times New Roman",Font.PLAIN,18);
    	g.setFont(font);
    	//设置相关颜色等等
    	g.setColor(Color.BLACK);
    	g.drawRect(0,0,width-1,height-1);
    	g.setColor(Color.GRAY);
    

      以上创建了一个基本的验证码图片,注意很多时候如果要反复对象对某个对象进行修改操作时(如某个字符串,需要反复进行拼接操作时,为提高性能,一般选择用缓冲类的对象进行操作之后再转换为相关对象)。以上是产生验证码的gui主要代码,具体的步骤不啰嗦了,请参考代码吧。

    2、创建好相关的验证码图片界面之后,下一步就是产生随机数了,请先看以下代码:

    //2、产生随机数
    	//定义生成随机数的对象
    	Random random = new Random();
    	//产生干扰线
    	for(int i=0;i<40;i++){
    		//设置40条干扰线
    		int x1 = random.nextInt(width);
    		int y1 = random.nextInt(height);
    		int x2 = random.nextInt(10);
    		int y2 = random.nextInt(10);
    		//将随机线条描绘到验证码对象中
    		g.drawLine(x1,y1,x1+x2,y1+y2);
    	}
    	//产生随机数
    	//定义随机数的个数
    	int length = 4
    	//定义 变量存储随机数字变量
    	BufferedString str_random = new BufferedString();//定义成缓冲字符类型是为了提高效率
    	for(int i=0;i<length;i++){
    		int num_random = random.nextInt(10);
    		String str_num = String.valueOf(num_random);
    		g.drawString(str_num);
    		str_random.append(str_num);
    	}
    

      以上主要通过Random随机数产生对象来产生随机数字,其中注意要在反复第String类型操作的时候,将其定义成BufferedString进行操作比较高效。具体的操作并没有涉及什么新技术,请查看代码。

    3、完成产生随机数的步骤之后,剩下的就是将产生的随机数发送出去了。请看代码

    //3、发送验证码图片数据
    	bufferedImg.flush();//刷新与图像缓冲有关的数据
    	g.dispose();//释放与Graphice2D有关的对象的资源
    	String randomCode = str_random.toString();
    	session.setAttribute("randomCode",randomCode.toString());//通过session传递随机码给其他页面用于验证身份
    	ServletOutputStream outputStream = response.getOutputStream();
    	ImageIO.write(bufferedImg,"jpeg",outputStream);
    	
    	outputStream.close();
    	
    	out.clear();
    	out=pageContext.pushBody();
    

      以上的发送验证码也是比较简单,只是通过网络流进行发送操作,其中,注意Graphics2D的资源释放和IO流的关闭就好了。其中,将验证码通过session发送给其他页面使用。

    三、总结

    以上实现了简单的数字验证码功能,其中涉及到的技术主要是javaGUI、IO操作和servlet技术的session技术。类似的,实现算式的验证码也是类似的步骤,具体的就不多说,下面的代码是实现了简单的算式验证码的代码参考:

    int width = 70,height = 22;
    	if(request.getParameter("width")!=null){
    		try{
    			width=Integer.parseInt(request.getParameter("width"));
    		}catch(NumberFormatException e) {
    			
    		}
    	}
    	BufferedImage bufferedImg = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
    	Graphics2D g = bufferedImg.createGraphics();
    	
    	g.setColor(Color.WHITE);
    	g.fillRect(0,0,width,height);
    	
    	Font font = new Font("Times New Roman",Font.PLAIN,18);
    	g.setFont(font);
    	
    	g.setColor(Color.BLACK);
    	g.drawRect(0,0,width-1,height-1);
    	g.setColor(Color.GRAY);
    	
    	Random random = new Random();//设置随机种子
    	
    	for(int i=0;i<40;i++){
    		//设置40条干扰线
    		int x1 = random.nextInt(width);
    		int y1 = random.nextInt(height);
    		int x2 = random.nextInt(10);
    		int y2 = random.nextInt(10);
    		g.drawLine(x1,y1,x1+x2,y1+y2);
    	}
    	
    	int length = 4;//设置默认生成四个长度的验证码
    	if(request.getParameter("length")!=null){
    		try{
    			length = Integer.parseInt(request.getParameter("length"));
    		}catch(NumberFormatException e){
    			out.println("<script>alert('无法加载验证码,请重新操作!')</script");
    			e.printStackTrace();
    		}
    	}
    	//定义变量存储运算结果
    	int result = 0;
    	//定义一个int用于存储某个数字后面的运算符,1代表+,2代表-,初始化为0
    	int int_sign = 0;
    	for(int i = 0;i<length;i++){//获取随机数字字符串
    		int num_random = random.nextInt(10);
    		//根据符号标记标量int_sign进行相应的运算
    		if(int_sign==2){
    			result = result - num_random;
    		}else{
    			result = result + num_random;
    		}
    		String strRand = String.valueOf(num_random);
    		g.setColor(Color.RED);
    		g.drawString(strRand,13 * i + 6, 16);
    		//随机获取运算符号
    		if(i<length-1){
    			int sign_random = random.nextInt(2);
    			if(sign_random<1){
    				g.setColor(Color.GREEN);
    				g.drawString("+",13 * i + 12, 16);
    				int_sign = 1;
    			}else{
    				g.setColor(Color.BLUE);
    				g.drawString("-",13 * i + 12, 16);
    				int_sign = 2;
    			}
    		}else{
    			g.drawString("=?",13 * i + 12, 16);
    		}
    		
    	}
    	bufferedImg.flush();
    	g.dispose();
    	
    	session.setAttribute("randomCode",result);
    	
    	response.setContentType("image/jpeg");
    	response.setHeader("Pragam","no-cache");
    	response.setHeader("Cache-Control","no-cache");
    	response.setDateHeader("Expires",0);
    	
    	ServletOutputStream outputStream = response.getOutputStream();
    	ImageIO.write(bufferedImg,"jpeg",outputStream);
    	
    	outputStream.close();
    	
    	out.clear();
    	out=pageContext.pushBody();
    	
    

      好了,验证码的总结就到此结束,有什么不足的地方请各位大神指正!

  • 相关阅读:
    一步步搭建自己的web服务器
    http协议知识整理
    数据库系统原理-第一章 数据库系统基本概念
    程序设计入门-C语言基础知识-翁恺-第七周:指针与字符串-详细笔记(七)
    程序设计入门-C语言基础知识-翁恺-第六周:数组-详细笔记(六)
    程序设计入门-C语言基础知识-翁恺-第五周:函数-详细笔记(五)
    程序设计入门-C语言基础知识-翁恺-期中测试
    程序设计入门-C语言基础知识-翁恺-第四周:循环控制-详细笔记(四)
    程序设计入门-C语言基础知识-翁恺-第三周:循环-详细笔记(三)
    程序设计入门-C语言基础知识-翁恺-第二周:简单的计算程序-详细笔记(二)
  • 原文地址:https://www.cnblogs.com/lcplcpjava/p/5814061.html
Copyright © 2011-2022 走看看