现在springboot项目添加索引
<!--用户登录界面验证码-->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
书写配置类KaptchaConfig,和公共类KaptchaUtils
KaptchaConfig.class
@Component
public class KaptchaConfig {
@Bean
public DefaultKaptcha getDefaultKaptcha() {
com.google.code.kaptcha.impl.DefaultKaptcha defaultKaptcha = new com.google.code.kaptcha.impl.DefaultKaptcha();
Properties properties = new Properties();
// 图片边框
properties.setProperty("kaptcha.border", "no");
// 边框颜色
properties.setProperty("kaptcha.border.color", "black");
//边框厚度
properties.setProperty("kaptcha.border.thickness", "1");
// 图片宽
properties.setProperty("kaptcha.image.width", "120");
// 图片高
properties.setProperty("kaptcha.image.height", "40");
//图片实现类
properties.setProperty("kaptcha.producer.impl", "com.google.code.kaptcha.impl.DefaultKaptcha");
//文本实现类
properties.setProperty("kaptcha.textproducer.impl", "com.google.code.kaptcha.text.impl.DefaultTextCreator");
//文本集合,验证码值从此集合中获取
properties.setProperty("kaptcha.textproducer.char.string", "01234567890");
//验证码长度
properties.setProperty("kaptcha.textproducer.char.length", "4");
//字体
properties.setProperty("kaptcha.textproducer.font.names", "宋体");
//字体颜色
properties.setProperty("kaptcha.textproducer.font.color", "black");
//文字间隔
properties.setProperty("kaptcha.textproducer.char.space", "5");
//干扰实现类
properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.DefaultNoise");
//干扰颜色
properties.setProperty("kaptcha.noise.color", "blue");
//干扰图片样式
properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.WaterRipple");
//背景实现类
properties.setProperty("kaptcha.background.impl", "com.google.code.kaptcha.impl.DefaultBackground");
//背景颜色渐变,结束颜色
properties.setProperty("kaptcha.background.clear.to", "white");
//文字渲染器
properties.setProperty("kaptcha.word.impl", "com.google.code.kaptcha.text.impl.DefaultWordRenderer");
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
公共类KaptchaUtils.class
public class KaptchaUtils {
/**
* 生成验证码图片
* @param request 设置session
* @param response 转成图片
* @param captchaProducer 生成图片方法类
* @param validateSessionKey session名称
* @throws Exception
*/
public static void validateCode(HttpServletRequest request, HttpServletResponse response, DefaultKaptcha captchaProducer, String validateSessionKey) throws Exception{
// Set to expire far in the past.
response.setDateHeader("Expires", 0);
// Set standard HTTP/1.1 no-cache headers.
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
// Set IE extended HTTP/1.1 no-cache headers (use addHeader).
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
// Set standard HTTP/1.0 no-cache header.
response.setHeader("Pragma", "no-cache");
// return a jpeg
response.setContentType("image/jpeg");
// create the text for the image
String capText = captchaProducer.createText();
// store the text in the session
request.getSession().setAttribute(validateSessionKey, capText);
// create the image with the text
BufferedImage bi = captchaProducer.createImage(capText);
ServletOutputStream out = response.getOutputStream();
// write the data out
ImageIO.write(bi, "jpg", out);
try {
out.flush();
} finally {
out.close();
}
}
}
写完后我们来写前端的代码
<div class="control-group">
<div class="controls" style="text-align: center">
<img src="/loginValidateCode" th:src="@{/user/loginValidateCode}" id="loginValidateCode" name="loginValidateCode"
onclick="uploadLoginValidateCode()" class="m-margin-bottom" alt="">
<input type="text" id="validateCode" name="validateCode" class="form-control" style="width: 200px">
</div>
</div>
先一个可以装验证码图片,并且给它id:loginValidateCode,以及点击的事件uploadLoginValidateCode()
th:src="@{/user/loginValidateCode}"是图片的路径 由于springboot要使用thymeleaf
故必须在html上头添加
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
显示图片书写完毕后 写触发的事件
function uploadLoginValidateCode() {
/*路径一定要加上项目的跟路径*/
$("#loginValidateCode").attr("src","/user/loginValidateCode?random="+new Date().getMilliseconds());
}
接下来书写后端的代码
/**
* 登录验证码SessionKey
*/
public static final String LOGIN_VALIDATE_CODE = "login_validate_code";
/**
* 登录验证码图片
*/
@GetMapping("/loginValidateCode")
public void loginValidateCode(HttpServletRequest request, HttpServletResponse response) throws Exception {
KaptchaUtils.validateCode(request,response,kaptchaProducer,LOGIN_VALIDATE_CODE);
}
你会发现为啥这边只有@GetMapping("/loginValidateCode"),而图片的地址是@{/user/loginValidateCode}
这是由于我在编写Controller的时候有个习惯 喜欢在前面添加有关该类的@RequestMapping("/user")
这样我们就可以点击图片更换验证码了
接下来把前端的所有代码贴出来
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head >
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>注册登录</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.css">
<link rel="stylesheet" href="../../static/css/me.css" th:href="@{/css/me.css}">
<style>
.error{
color: #b96027;
}
</style>
</head>
<body>
<br>
<br>
<br>
<div class="m-container-small m-padded-tb-massive" style="max-width: 30em !important;">
<div class="ur container">
<div class="ui middle aligned center aligned grid">
<div class="column">
<h2 class="ui teal image header">
<div class="content">
用户登录登录
</div>
</h2>
<form class="ui large form" method="post" action="#" id="loginform" th:action="@{/user/login}">
<div class="ui segment" style="position: relative;">
<div class="field">
<div class="ui left icon input">
<i class="user icon"></i>
<input type="text" name="username" placeholder="用户名">
</div>
</div>
<div class="field">
<div class="ui left icon input">
<i class="lock icon"></i>
<input type="password" name="password" placeholder="密码">
</div>
</div>
<div class="control-group">
<div class="controls" style="text-align: center">
<img src="/loginValidateCode" th:src="@{/user/loginValidateCode}" id="loginValidateCode" name="loginValidateCode"
onclick="uploadLoginValidateCode()" class="m-margin-bottom" alt="">
<input type="text" id="validateCode" name="validateCode" class="form-control" style="width: 200px">
<p style="color: #b96027" id="validateCodeError"></p>
</div>
</div>
<button class="ui teal submit button">登 录</button>
<a href="register.html" th:href="@{/user/register}" style="position: absolute;right: 30px;bottom: 10px;">注 册</a>
</div>
<div class="ui error mini message"></div>
<div class="ui mini negative message" th:unless="${#strings.isEmpty(message)}" th:text="${message}">
用户名和密码错误
</div>
</form>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.js"></script>
<script>
$('.ui.form').form({
fields: {
username: {
identifier: 'username',
rules: [{
type: 'empty',
prompt: '请输入用户名'
}]
},
password: {
identifier: 'password',
rules: [{
type: 'empty',
prompt: '请输入密码'
}]
}
}
});
function uploadLoginValidateCode() {
/*路径一定要加上项目的跟路径*/
$("#loginValidateCode").attr("src","/user/loginValidateCode?random="+new Date().getMilliseconds());
}
</script>
</body>
</html>
后端的代码
@Controller
@RequestMapping("/user")
public class UserLoginController {
@Resource
private DefaultKaptcha kaptchaProducer;
@Autowired
private UserMapper userMapper;
@GetMapping
public String Login(){
return "user/login";
}
/**
* 登录校验表单以及验证码
* @param validateCode
*/
@PostMapping("/login")
public String login(@RequestParam("validateCode")String validateCode,
@RequestParam String username,
@RequestParam String password,
HttpSession session, RedirectAttributes attributes,
HttpServletRequest request){
String loginValidateCode = request.getSession().getAttribute(LOGIN_VALIDATE_CODE).toString();
User user = userMapper.FindUserByUsername(username);
if (validateCode==null){
attributes.addFlashAttribute("message","请输入验证码");
return "redirect:/user";
}else if (!validateCode.equals(loginValidateCode)){
attributes.addFlashAttribute("message","验证码错误");
}else {
if(user == null){
attributes.addFlashAttribute("message","用户不存在");
return "redirect:/user";
}else if(user.getPassword().equals(password)){
user.setPassword(null);
session.setAttribute("username",username);
return "redirect:/";
}else{
attributes.addFlashAttribute("message","用户名或密码错误");
return "redirect:/user";
}
}
return "redirect:/user";
}
/**
* 登录验证码SessionKey
*/
public static final String LOGIN_VALIDATE_CODE = "login_validate_code";
/**
* 登录验证码图片
*/
@GetMapping("/loginValidateCode")
public void loginValidateCode(HttpServletRequest request, HttpServletResponse response) throws Exception {
KaptchaUtils.validateCode(request,response,kaptchaProducer,LOGIN_VALIDATE_CODE);
}
@GetMapping("/logout")
public String logout(HttpSession session){
session.removeAttribute("username");
return "redirect:/user";
}
}
最后有什么问题请指出 谢谢大家!!!