Spring boot 集成Kaptcha生成验证码
Spring boot 集成Kaptcha生成验证码
SpringCloud 项目中注册生成验证码示例
第一步:引入包
<!--验证码依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>kaptcha-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
第二步:编写Controller层
/**
* @类名 KaptchaController
* @描述 验证码生成及校验
* @作者
* @日期
**/
import com.alibaba.fastjson.JSONObject;
import com.cngrain.userweb.service.KaptchaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/kaptcha")
public class KaptchaController {
@Autowired
private KaptchaService kaptcha;
/**
* @名称 render
* @描述 生成验证码
* @参数 []
* @返回值 com.alibaba.fastjson.JSONObject
* @作者
* @时间
*/
@GetMapping("/render")
public JSONObject render() {
JSONObject jsonObject = new JSONObject();
try {
String code = kaptcha.render();
if(null != code && !"".equals(code)){
jsonObject.put("success",true);
jsonObject.put("message","验证渲染成功!");
jsonObject.put("data",code);
}else{
jsonObject.put("success",false);
jsonObject.put("message","验证渲染失败!");
jsonObject.put("data","");
}
} catch (Exception e) {
jsonObject.put("success",false);
jsonObject.put("message","验证渲染失败:" + e.getMessage());
jsonObject.put("data","");
}
return jsonObject;
}
/**
* @名称 validDefaultTime
* @描述 验证码校验
* @参数 [code]
* @返回值 com.alibaba.fastjson.JSONObject
* @作者
* @时间
*/
@PostMapping("/valid")
public JSONObject validDefaultTime(@RequestParam String code) {
//default timeout 900 seconds
JSONObject jsonObject = new JSONObject();
try {
if(kaptcha.validate(code)){
jsonObject.put("success",true);
jsonObject.put("message","验证成功!");
jsonObject.put("data","");
}else{
jsonObject.put("success",false);
jsonObject.put("message","验证码有误!");
jsonObject.put("data","");
}
} catch (Exception e) {
jsonObject.put("success",false);
jsonObject.put("message","验证失败:" + e.getMessage());
jsonObject.put("data","");
}
return jsonObject;
}
@PostMapping("/validTime")
public void validWithTime(@RequestParam String code) {
kaptcha.validate(code, 60);
}
}
第三步:编写Service层
public interface KaptchaService {
/**
* @名称 render
* @描述 生成验证码
* @参数 []
* @返回值 java.lang.String
* @作者
* @时间
*/
String render();
/**
* @名称 validate
* @描述 验证码校验,默认超时15分钟(900s)
* @参数 [code]
* @返回值 boolean
* @作者
* @时间
*/
boolean validate(String code) throws Exception;
/**
* 校对验证码
*
* @param code 需要验证的字符串
* @param second 超时时间(秒)
* @return 是否验证成功
* @see com.baomidou.kaptcha.exception.KaptchaException
*/
boolean validate(String code, long second);
}
第四步:编写ServiceImpl层
import com.baomidou.kaptcha.exception.*;
import com.cngrain.userweb.service.KaptchaService;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
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.io.IOException;
import static com.google.code.kaptcha.Constants.KAPTCHA_SESSION_DATE;
import static com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY;
/**
* @类名 KaptchaServiceImpl
* @描述
* @作者
* @日期
**/
@Service
@Slf4j
public class KaptchaServiceImpl implements KaptchaService {
private DefaultKaptcha kaptcha;
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
public KaptchaServiceImpl(DefaultKaptcha kaptcha) {
this.kaptcha = kaptcha;
}
/**
* @名称 render
* @描述 生成验证码
* @参数 []
* @返回值 java.lang.String
* @作者
* @时间
*/
@Override
public String render() {
response.setDateHeader(HttpHeaders.EXPIRES, 0L);
response.setHeader(HttpHeaders.CACHE_CONTROL, "no-store, no-cache, must-revalidate");
response.addHeader(HttpHeaders.CACHE_CONTROL, "post-check=0, pre-check=0");
response.setHeader(HttpHeaders.PRAGMA, "no-cache");
response.setContentType("image/jpeg");
String sessionCode = kaptcha.createText();
try (ServletOutputStream out = response.getOutputStream()) {
request.getSession().setAttribute(KAPTCHA_SESSION_KEY, sessionCode);
request.getSession().setAttribute(KAPTCHA_SESSION_DATE, System.currentTimeMillis());
ImageIO.write(kaptcha.createImage(sessionCode), "jpg", out);
return sessionCode;
} catch (IOException e) {
throw new KaptchaRenderException(e);
}
}
/**
* @名称 validate
* @描述 验证码校验,默认超时15分钟(900s)
* @参数 [code]
* @返回值 boolean
* @作者
* @时间
*/
@Override
public boolean validate(String code) throws Exception {
boolean success = false;
try {
success = validate(code, 900);
}catch (KaptchaException kaptchaException){
if (kaptchaException instanceof KaptchaIncorrectException) {
throw new Exception("验证码不正确");
} else if (kaptchaException instanceof KaptchaNotFoundException) {
throw new Exception("验证码未找到");
} else if (kaptchaException instanceof KaptchaTimeoutException) {
throw new Exception("验证码过期");
} else {
throw new Exception("验证码渲染失败");
}
}
return success;
}
/**
* @名称 validate
* @描述 验证码校验,默认超时15分钟(900s)
* @参数 [code, second]
* @返回值 boolean
* @作者
* @时间
*/
@Override
public boolean validate(@NonNull String code, long second) {
HttpSession httpSession = request.getSession(false);
String sessionCode;
if (httpSession != null && (sessionCode = (String) httpSession.getAttribute(KAPTCHA_SESSION_KEY)) != null) {
if (sessionCode.equalsIgnoreCase(code)) {
long sessionTime = (long) httpSession.getAttribute(KAPTCHA_SESSION_DATE);
long duration = (System.currentTimeMillis() - sessionTime) / 1000;
if (duration < second) {
httpSession.removeAttribute(KAPTCHA_SESSION_KEY);
httpSession.removeAttribute(KAPTCHA_SESSION_DATE);
return true;
} else {
throw new KaptchaTimeoutException();
}
} else {
throw new KaptchaIncorrectException();
}
} else {
throw new KaptchaNotFoundException();
}
}
}
前台代码展示
<!--验证码-->
<tr>
<td class="input_title"><i>*</i><h5>验证码</h5></td>
<td class="input_box" colspan="3">
<input id="validCode" type="text" style="width:170px">
<img id="validCodeImg" style="width: 90px;height: 36px;margin-bottom: -12px;" src="registerValidCodeRender">
<a onclick="changeValidCode()"><label>看不清?</label></a>
<span id="validCodeError">错误信息</span>
</td>
</tr>
/* 加载验证码 */
function changeValidCode() {
$("#validCodeImg")[0].src = registerValidCodeRender;
}
/* 检验验证码 */
function checkValidCode() {
$.ajax({
url: registerValidCodeCheck,
type: 'post',
data: {
'code': $('#validCode').val()
},
dataType: 'json',
async: false,
success: function (data) {
if (data.success) {
toLogin();
}else{
$("#log_failure").html(data.message);
$("#validCode").val("");
$('#validCode').focus();
}
},
error: function (data) {
backMessage("验证码有误!",$("#validCodeError"));
return false;
}
});