1.在pom文件中加载验证码依赖
<!--验证码依赖-->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
2.在applicationContext中加入bean
<!--图片格式验证码-->
<bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
<property name="config">
<bean class="com.google.code.kaptcha.util.Config">
<constructor-arg>
<props>
<prop key="kaptcha.border">no</prop>
<prop key="kaptcha.image.width">120</prop>
<prop key="kaptcha.session.key">code</prop>
<prop key="kaptcha.textproducer.font.color">blue</prop>
<prop key="kaptcha.textproducer.font.size">40</prop>
<prop key="kaptcha.textproducer.char.length">4</prop>
</props>
</constructor-arg>
</bean>
</property>
</bean>
3.在controller中加入以下方法获得验证码图片:
private final String VALIDATE_CODE = "VALIDATE_CODE";
private final String EXPIRE_TIME = "EXPIRE_TIME";
@RequestMapping(value = "/getValidateCode.do",method = GET)
public void getJpg(HttpServletRequest request, HttpServletResponse response){
try {
HttpSession session = request.getSession();
// 设置清除浏览器缓存
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setContentType("image/png");
// 验证码一分钟内有效
long expireTime = System.currentTimeMillis() + 60000;
// 将验证码放到session中
String validateCode = captchaProducer.createText();
session.setAttribute(VALIDATE_CODE, EncodeBase64.encodeBase64(validateCode));//将加密后的验证码放到session中,确保安全
session.setAttribute(EXPIRE_TIME, expireTime);
// 输出验证码图片
BufferedImage bufferedImage = captchaProducer.createImage(validateCode);
ServletOutputStream out = response.getOutputStream();
ImageIO.write(bufferedImage, "png", out);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
其中:EncodeBase64工具类代码:
public class EncodeBase64 {
public static String encodeBase64(String str) {
final Base64.Encoder encoder = Base64.getEncoder();
byte[] textByte = new byte[0];
try {
textByte = str.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return encoder.encodeToString(textByte);
}
}
4.在前端jsp页面内加入获得验证码的标签:
<div style="width: 200px; position: relative;top: 40px;">
<input id="validateCode" class="form-control" type="text" maxlength="4" placeholder="验证码" onblur=trim("#loginPwd")>
</div>
<div style="position: relative;top: -5px;left: 210px">
<img id="validateCodeImage" src="setting/user/getValidateCode.do" style="width: 130px;height: 45px;">
</div>
以及点击重新获取验证码的jquery操作:
$(function () {
$("#validateCodeImage").click(function () {
loadValidateCode();
})
}
// 加载验证码
function loadValidateCode() {
var time = new Date().getTime();
//id的作用是防止浏览器缓存
$("#validateCodeImage").prop('src','setting/user/getValidateCode.do?id='+time+'')
}
5.后端验证验证码是否正确:
@RequestMapping(value = "/logIn.do",method = POST)
@ResponseBody
public Object logIn(String loginAct, String loginPwd,String validateCode, HttpServletRequest request){
try {
//判断验证码是否过期
if(System.currentTimeMillis()>(Long)request.getSession().getAttribute("EXPIRE_TIME")){
throw new LoginException("验证码过期,重新输入");
}
//判断验证码是否错误
String currentCode = (String) request.getSession().getAttribute("VALIDATE_CODE");
if(!currentCode.equals(EncodeBase64.encodeBase64(validateCode))){
throw new LoginException("验证码输入错误,重新输入");
}
json = WriteJsonUntil.printJsonFlag(true);
} catch (LoginException e) {
e.printStackTrace();
String msg =e.getMessage();
Map<String,Object> map = new HashMap<>();
map.put("success",false);
map.put("msg",msg);
json = WriteJsonUntil.printJsonObj(map);
}
return json;
}