SSM之一点一滴:使用Graphics2D绘制web动态验证码、干扰线完整描述

B/S搭建的SSM项目,使用验证码将提高项目的安全性。完成验证码功能的方法在代码中都有注释,在此不做描述

验证码功能:

1、由五位字母加数字构成,字母区分大小写

2、验证码图片中绘制干扰线

验证码效果:

实现代码如下:

//使用RequestMapping("/getVerifyCode")前端调用验证码功能,并将验证码保存在session中,进行前端验证码与后台验证码的对比
	@RequestMapping("/getVerifyCode")
	public void getVerifyCode(HttpServletResponse response,HttpSession session) {
		ByteArrayOutputStream output =new ByteArrayOutputStream();
		session.setAttribute("verifyCode",drawCodeImg(output));
		try {
			ServletOutputStream out =response.getOutputStream();
			output.writeTo(out);
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
//生成验证码
private String drawCodeImg(ByteArrayOutputStream output) {
		String code = "";
        //使用randomChar方法随机生成五位验证码
		for (int i = 0; i < 5; i++) {
			code += randomChar();
		}
		
		int width = 70;
		int height = 36;
		// 生成随机数,用于后面的验证码输出
		Random ran = new Random();
		// 图像buffer
		//创建BufferedImage对象
		BufferedImage bImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); 
		//使用BufferedImage对象得到Graphics对象
		Graphics2D graphics = bImage.createGraphics();     										
		// 设置字体类型、字体大小、字体样式
		Font font = new Font("Times New Roman", Font.PLAIN, 20);
		graphics.setFont(font);
		// 将随机得到的字体颜色绘制内容
		//随机得到颜色用于绘制内容
		graphics.setColor(new Color(ran.nextInt(255)+1,ran.nextInt(255)+1,ran.nextInt(255)+1));		
		//绘制背景的代码
		graphics.setBackground(Color.WHITE);
		//擦除一个由参数指定的矩形块的着色。通过使用当前绘图表面的背景色进行填充来清除指定的矩形,解决返回图像背景黑色问题。
		graphics.clearRect(0, 0, width, height);
		//绘制干扰线。i为干扰线条数
		for (int i = 0; i<(ran.nextInt(5)+8); i++) {
		    //设置干扰线的颜色
		    graphics.setColor(new Color(ran.nextInt(255)+1,ran.nextInt(255)+1,ran.nextInt(255)+1));	
			//设置干扰线的坐标
			graphics.drawLine(ran.nextInt(70),ran.nextInt(36),ran.nextInt(70),ran.nextInt(36));				
			}
		//获取一个字符串在屏幕上的尺寸
		FontRenderContext context = graphics.getFontRenderContext();
		Rectangle2D bounds = font.getStringBounds(code, context);
		double x = (width - bounds.getWidth()) / 2;
        double y = (height - bounds.getHeight()) / 2;
        double ascent = bounds.getY();
        double baseY = y - ascent;
        //此步为在x坐标为((int) x)y坐标为(int) baseY的地方绘制内容为code的字符图。
        graphics.drawString(code, (int) x, (int) baseY);
        //dispose()作用是销毁程序中指定的图形界面资源,如果在使用了graphics获得windows一些图形资源,而不进行关闭的话,由于后期多人使用就会造成内存溢出的情况的,导致程序卡死。
        //类似java 连接数据库时使用conn.close方法,也是为了关闭数据库连接资源。
        graphics.dispose();
       //如果是网站则可以把图片保存到项目下面然后页面上取出来即可
        try {
			ImageIO.write(bImage, "jpg", output);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return code;
	}

//返回一个随机数字
private char randomChar() {
		//由Random生成随机数
		Random r = new Random();
		//定义一个字符串(A-Z,a-z,0-9)即62位;
		String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz0123456789";
		//charAt() 方法返回指定索引处的char值。
		return str.charAt(r.nextInt(str.length()));
	}

代码测试

因为我使用的是SSM架构搭建的系统,所以在测试验证码功能是否成功时,直接用URL进行测试,测试验证码URL地址

http://localhost:8080/SongSSM/userController/getVerifyCode

http://localhost:[端口号]/[项目名]/[controller控制器]/[控制器下面的方法]

测试结果

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值