验证码的作用
案例要求
前端页面准备
因为涉及到jQuery,所以需要在resources/static创建目录,存放jQuery库
准备login.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<!--引入jQuery -->
<script type="text/javascript" src="/js/jquery-1.8.3.min.js"></script>
</head>
<body>
<h2>用户登录</h2>
<form action="/login" method="post">
用户名:<input type="text" name="username"><br><br>
密码 :<input type="password" name="password"><br><br>
验证码:<input id="identify-input" type="text" name="identifyCode">
<img id="identify-img" src="/identifyImage"><br><br>
<input type="submit" value="登录">
</form>
<!--绑定点击事件 -->
<script>
$("#identify-img").on('click',function (){
// 点击验证码那个图片的时候,我们输入的验证码那个框就会清空
$('#identify-input').val('')
//而且我们点击验证码的时候,希望它可以改变验证码内容,其实是通过发送新请求来改变验证码内容
$('#identify-img').attr('src','/identifyImage?'+Math.random())
})
</script>
</body>
</html>
随机验证码工具类
public class IdentifyCodeUtils {
//设置图片宽
private int width = 95;
//设置图片高度
private int height = 25;
//设置干扰线数量
private int lineSize = 40;
//随机产生数字和字母组合的字符串
private String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private Random random = new Random();
/**
* 获得字体
*/
private Font getFont() {
return new Font("Fixedsys", Font.CENTER_BASELINE, 18);
}
/**
* 获得颜色
*/
private Color getRandColor(int fc, int bc) {
if (fc > 255) {
fc = 255;
}
if (bc > 255) {
bc = 255;
}
int r = fc + random.nextInt(bc - fc - 16);
int g = fc + random.nextInt(bc - fc - 14);
int b = fc + random.nextInt(bc - fc - 18);
return new Color(r, g, b);
}
/**
* 获取验证码
*
* @return
*/
public String getIdentifyCode() {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < 4; i++) {
char c = randString.charAt(random.nextInt(randString.length()));
buffer.append(c);
}
return buffer.toString();
}
/**
* 生成随机图片
*
* @param identifyCode
* @return
*/
public BufferedImage getIdentifyImage(String identifyCode) {
//BufferedImage类是具有缓冲区的Image类,Image类是用来描述图像信息的类
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
//产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
Graphics graphics = image.getGraphics();
//图片大小
graphics.fillRect(0, 0, width, height);
//字体大小
graphics.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));
//字体颜色
graphics.setColor(getRandColor(110, 133));
//绘制干扰线
for (int i = 0; i <= lineSize; i++) {
drawLine(graphics);
}
//绘制随机字符
drawString(graphics, identifyCode);
graphics.dispose();
return image;
}
/**
* 绘制字符串
*/
private void drawString(Graphics g, String identifyCode) {
for (int i = 0; i < identifyCode.length(); i++) {
g.setFont(getFont());
g.setColor(new Color(random.nextInt(101), random.nextInt(111), random
.nextInt(121)));
g.translate(random.nextInt(3), random.nextInt(3));
g.drawString(String.valueOf(identifyCode.charAt(i)), 13 * i + 20, 18);
}
}
/**
* 响应验证码图片
*
* @param identifyImg
* @param response
*/
public void responseIdentifyImg(BufferedImage identifyImg, HttpServletResponse response) {
//设置响应类型,告诉浏览器输出的内容是图片
response.setContentType("image/jpeg");
//设置响应头信息,告诉浏览器不用缓冲此内容
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expire", 0);
try {
//把内存中的图片通过流动形式输出到客户端
ImageIO.write(identifyImg, "JPEG", response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 绘制干扰线
*/
private void drawLine(Graphics graphics) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(13);
int yl = random.nextInt(15);
graphics.drawLine(x, y, x + xl, y + yl);
}
}
后端控制器
@Controller
public class UserController {
@RequestMapping("/loginShow")
public String loginShow(){
return "login.html";
}
@PostMapping("/login")
public String login(String username,String password,String identifyCode,HttpSession session){
System.out.println("用户名:"+username);
System.out.println("密码:"+password);
System.out.println("验证码:"+identifyCode);
//从session中取出验证码
String sessionCode = (String)session.getAttribute("identifyFyCode");
if (identifyCode.equalsIgnoreCase(sessionCode)){
System.out.println("验证码正确");
//进行登录判断的逻辑大家自己写,这里就不演示了
}else{
System.out.println("验证码错误");
//重定向到登录画面
return "redirect:/loginShow";
}
return "";
}
/**
* 给前端返回一个验证码图片
* @return
*/
@RequestMapping("/identifyImage")
public void identifyImage(HttpServletResponse response, HttpSession session){
//创建随机验证码
IdentifyCodeUtils utils = new IdentifyCodeUtils();
String identifyCode = utils.getIdentifyCode();
//session存入验证码
session.setAttribute("identifyCode", identifyCode);
//根据验证码创建图片
BufferedImage identifyImage = utils.getIdentifyImage(identifyCode);
//回传给前端
utils.responseIdentifyImg(identifyImage,response);
}
}
测试
当我们点击验证码这个图片的时候,它就会生成新验证码
并且如果我们在输入框中如果有写验证码的话,当我们点击验证码图片,它就会把输入框内容清空(大家自己测试)