1. 什么是EasyCaptcha

Java图形验证码,支持gif、中文、算术等类型,可用于Java Web、JavaSE等项目。

源码地址: https://github.com/whvcse/EasyCaptcha

2. 添加依赖

<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
<version>1.6.2</version>
</dependency>

以下内容是对EasyCaptcha封装,生成的验证码储存到redis中。

3. 创建验证码接口

新建文件: EasyCaptchaService.java

package com.hui.javalearn.service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* 验证码类
* https://github.com/whvcse/EasyCaptcha
*/
public interface EasyCaptchaService {
/**
* 验证码宽度
*/
Integer CAPTCHA_WIDTH = 130;
/**
* 验证码高度
*/
Integer CAPTCHA_HEIGHT = 48;

/**
* 验证码长度
*/
Integer CAPTCHA_LENGTH = 4;

/**
* 验证码缓存key前缀
*/
String CAPTCHA_KEY_PRE = "CAPTCHA:LIST:";

/**
* 验证码缓存时间
*/
Integer CAPTCHA_CACHE_TIME = 120;

/**
* 验证码类型: 默认图片
* */
int CAPTCHA_TYPE_DEFAULT_PNG = 10;
/**
* 验证码类型: 动态GIF
* */
final int CAPTCHA_TYPE_GIF = 20;
/**
* 验证码类型: 中文
* */
final int CAPTCHA_TYPE_CHINESE = 30;
/**
* 验证码类型: 动态中文
* */
final int CAPTCHA_TYPE_GIF_CHINESE = 40;
/**
* 验证码类型: 算术
* */
final int CAPTCHA_TYPE_ARITHMETIC = 50;

/**
* 生成普通图片验证码
* @param uuid
* @param request
* @param response
* @return
*/
String outputCaptchaImg(String uuid, Integer type,HttpServletRequest request, HttpServletResponse response) throws IOException;

/**
* 校验图片验证码
* @param uuid
* @param captchaCode
* @return
*/
boolean verifyCaptchaCode(String uuid,String captchaCode);
}

4. 实现验证码接口

新建文件: EasyCaptchaServiceImpl.java

package com.hui.javalearn.service.Impl;

import com.hui.javalearn.common.enums.ResultEnum;
import com.hui.javalearn.exception.ApiException;
import com.hui.javalearn.service.EasyCaptchaService;
import com.wf.captcha.*;
import com.wf.captcha.utils.CaptchaUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
public class EasyCaptchaServiceImpl implements EasyCaptchaService {
/**
* 注入redis
*/
@Autowired
private StringRedisTemplate stringRedisTemplate;

/**
* 保存验证码到缓存
*
* @param uuid
* @param codeValue
*/
private void saveCaptcha2Cache(String uuid, String codeValue) {
stringRedisTemplate.opsForValue().set(CAPTCHA_KEY_PRE + uuid, codeValue, CAPTCHA_CACHE_TIME, TimeUnit.SECONDS);
}

/**
*
* @param uuid
* @param type
* @param request
* @param response
* @return
* @throws IOException
*/
@Override
public String outputCaptchaImg(String uuid, Integer type, HttpServletRequest request, HttpServletResponse response) throws IOException {
String codeValue="";
switch (type) {
case CAPTCHA_TYPE_DEFAULT_PNG:
SpecCaptcha specCaptcha = new SpecCaptcha(CAPTCHA_WIDTH,CAPTCHA_HEIGHT,CAPTCHA_LENGTH);
codeValue = specCaptcha.text().toLowerCase();
CaptchaUtil.out(specCaptcha,request,response);
break;
case CAPTCHA_TYPE_GIF:
GifCaptcha gifCaptcha = new GifCaptcha(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, CAPTCHA_LENGTH);
codeValue = gifCaptcha.text().toLowerCase();
CaptchaUtil.out(gifCaptcha,request,response);
break;
case CAPTCHA_TYPE_CHINESE:
ChineseCaptcha chineseCaptcha = new ChineseCaptcha(CAPTCHA_WIDTH,CAPTCHA_HEIGHT,CAPTCHA_LENGTH);
codeValue = chineseCaptcha.text();
CaptchaUtil.out(chineseCaptcha,request,response);
break;
case CAPTCHA_TYPE_GIF_CHINESE:
ChineseGifCaptcha chineseGifCaptcha = new ChineseGifCaptcha(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, CAPTCHA_LENGTH);
codeValue = chineseGifCaptcha.text();
CaptchaUtil.out(chineseGifCaptcha,request,response);
break;
case CAPTCHA_TYPE_ARITHMETIC:
ArithmeticCaptcha arithmeticCaptcha = new ArithmeticCaptcha(CAPTCHA_WIDTH,CAPTCHA_HEIGHT);
codeValue = arithmeticCaptcha.text();
CaptchaUtil.out(arithmeticCaptcha,request,response);
break;
default:
throw new IOException("类型不存在");
}
saveCaptcha2Cache(uuid,codeValue);
return codeValue;
}

/**
* 校验图片验证码
* @param uuid
* @param captchaCode
* @return
*/
@Override
public boolean verifyCaptchaCode(String uuid, String captchaCode) {
String cacheCaptchaCode = stringRedisTemplate.opsForValue().get(CAPTCHA_KEY_PRE + uuid);
if (StringUtils.isBlank(cacheCaptchaCode)) {
throw new ApiException(ResultEnum.ERROR.getCode(),"图形验证码超时,请重新获取!");
}
if (!cacheCaptchaCode.equals(captchaCode.toLowerCase())){
throw new ApiException(ResultEnum.ERROR.getCode(),"图形验证码输入不正确!");
}
return true;
}
}

5. 使用

5.1 生成验证码

新建文件: CaptchaController.java

package com.hui.javalearn.controller;

import com.hui.javalearn.service.EasyCaptchaService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import java.io.IOException;

@Api(tags = "验证码")
@RestController
@RequestMapping("/captcha")
public class CaptchaController {

@Autowired
private EasyCaptchaService captchaService;

@GetMapping("/generate")
@ApiOperation("生成验证码")
public void generate(
HttpServletRequest request,
HttpServletResponse response,
@NotEmpty(message = "uuid不能为空") @RequestParam("uuid") String uuid
) throws IOException {
captchaService.outputCaptchaImg(uuid,EasyCaptchaService.CAPTCHA_TYPE_GIF,request,response);
}
}

5.2 校验验证码

...
// 校验图片验证码
easyCaptchaService.verifyCaptchaCode(uuid,captchaCode);
...