spring boot实现验证码登录
内容比较简单,需要完整项目的朋友留下邮箱,给你们发。
直接看效果:
下面是实现步骤
1.验证码生成工具类(引用自网络)
package com.laoxu.test.helloweb.util;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* @Description: 原始验证码生成工具
* @Author laoxu
* @Date 2019/11/2 23:01
**/
public class VerifyCodeUtil {
private int width = 90;// 定义图片的width
private int height = 20;// 定义图片的height
private static int codeCount = 4;// 定义图片上显示验证码的个数
private static int xx = 15;
private int fontHeight = 18;
private static int codeY = 16;
private static char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
/**
* 生成一个map集合
* code为生成的验证码
* codePic为生成的验证码BufferedImage对象
* @return
*/
public static Map<String,Object> generateCodeAndPic(int width, int height, int fontHeight) {
// 定义图像buffer
BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// Graphics2D gd = buffImg.createGraphics();
// Graphics2D gd = (Graphics2D) buffImg.getGraphics();
Graphics gd = buffImg.getGraphics();
// 创建一个随机数生成器类
Random random = new Random();
// 将图像填充为白色
gd.setColor(Color.WHITE);
gd.fillRect(0, 0, width, height);
// 创建字体,字体的大小应该根据图片的高度来定。
Font font = new Font("Fixedsys", Font.BOLD, fontHeight);
// 设置字体。
gd.setFont(font);
// 画边框。
gd.setColor(Color.BLACK);
gd.drawRect(0, 0, width - 1, height - 1);
// 随机产生40条干扰线,使图象中的认证码不易被其它程序探测到。
gd.setColor(Color.BLACK);
for (int i = 0; i < 30; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
gd.drawLine(x, y, x + xl, y + yl);
}
// randomCode用于保存随机产生的验证码,以便用户登录后进行验证。
StringBuffer randomCode = new StringBuffer();
int red = 0, green = 0, blue = 0;
// 随机产生codeCount数字的验证码。
for (int i = 0; i < codeCount; i++) {
// 得到随机产生的验证码数字。
String code = String.valueOf(codeSequence[random.nextInt(36)]);
// 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。
red = random.nextInt(255);
green = random.nextInt(255);
blue = random.nextInt(255);
// 用随机产生的颜色将验证码绘制到图像中。
gd.setColor(new Color(red, green, blue));
gd.drawString(code, (i + 1) * xx, codeY);
// 将产生的四个随机数组合在一起。
randomCode.append(code);
}
Map<String,Object> map =new HashMap<String,Object>();
//存放验证码
map.put("code", randomCode);
//存放生成的验证码BufferedImage对象
map.put("codePic", buffImg);
return map;
}
public static void main(String[] args) throws Exception {
//创建文件输出流对象
OutputStream out = new FileOutputStream("D://tmp/"+System.currentTimeMillis()+".jpg");
Map<String,Object> map = VerifyCodeUtil.generateCodeAndPic(90,20,18);
ImageIO.write((RenderedImage) map.get("codePic"), "jpeg", out);
System.out.println("验证码的值为:"+map.get("code"));
}
}
2.写登录页
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/login.css">
</head>
<body class="text-center">
<form class="form-signin">
<h1 class="h3 mb-3 font-weight-normal">请登录</h1>
<label for="username" class="sr-only">用户名:</label>
<input type="text" id="username" class="form-control" placeholder="" required="required" autofocus="">
<label for="password" class="sr-only">密码:</label>
<input type="password" id="password" class="form-control" placeholder="" required="required">
<div class="verify-div">
<label for="verify-code" class="sr-only">验证码:</label>
<input type="text" id="verify-code" style="width: 50%;" class="form-control" placeholder="" required="required">
<a href="#" onclick="changeVerifyCode()"><img id="imgObj" alt="验证码" src="/getVerifyCode"></a>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" id="submit">登录</button>
</form>
</body>
<script type="text/javascript" src="js/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
$(function() {
$("#submit").click(function (event) {
// 阻止表单默认提交
event.preventDefault();
var username = $("#username").val(), password = $("#password").val(),verifyCode=$("#verify-code").val();
if(username==""){
alert("用户名不能为空!");
return;
}
if(password==""){
alert("密码不能为空!");
return;
}
if(verifyCode==""){
alert("验证码不能为空!");
return;
}
// 提交验证
$.ajax({
type: "POST",
url: "/checkLogin",
data: {
"username": username,
"password": password,
"verifyCode": verifyCode
},
success: function (result) {
if(result=='success'){
window.location.href="http://localhost:8080/success.html";
}else{
alert(result);
}
}
});
});
});
function changeVerifyCode() {
var imgSrc = $("#imgObj");
var src = imgSrc.attr("src");
imgSrc.attr("src", chgUrl(src));
}
// 时间戳
// 为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳
function chgUrl(url) {
var timestamp = (new Date()).valueOf();
url = url.substring(0, 20);
if ((url.indexOf("&") >= 0)) {
url = url + "×tamp=" + timestamp;
} else {
url = url + "?timestamp=" + timestamp;
}
return url;
}
</script>
</html>
3.写controller
package com.laoxu.test.helloweb;
import com.laoxu.test.helloweb.util.VerifyCodeUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.util.Map;
/**
* @Description:
* @Author laoxu
* @Date 2019/11/2 13:35
**/
@Controller
public class LoginController {
@RequestMapping("/login")
public String index(){
return "forward:/login.html";
}
@RequestMapping("/getVerifyCode")
public void getVerifyCode(HttpServletRequest request, HttpServletResponse response){
// 调用工具类生成的验证码和验证码图片
Map<String, Object> codeMap = VerifyCodeUtil.generateCodeAndPic(90,20,18);
// 将四位数字的验证码保存到Session中。
HttpSession session = request.getSession();
session.setAttribute("verifyCode", codeMap.get("code").toString().toUpperCase());
// 禁止图像缓存。
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", -1);
response.setContentType("image/jpeg");
// 将图像输出到Servlet输出流中。
ServletOutputStream sos;
try {
sos = response.getOutputStream();
ImageIO.write((RenderedImage) codeMap.get("codePic"), "jpeg", sos);
sos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@ResponseBody
@RequestMapping("/checkLogin")
public String checkLogin(@RequestParam String username,
@RequestParam String password,
@RequestParam String verifyCode,
HttpServletRequest request){
String sessionVerifyCode = (String) request.getSession().getAttribute("verifyCode");
if(!"admin".equals(username)){
return "用户名错误!";
}
if(!"123".equals(password)){
return "密码错误!";
}
if(!sessionVerifyCode.equals(verifyCode.toUpperCase())){
return "验证码错误!";
}
return "success";
}
}
需要完整项目的朋友留下邮箱。
分类:
Java项目实战
标签:
java验证码
, spring boot验证码登录
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构