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控制器]/[控制器下面的方法]