1.首先是生成验证码
2.将生产的验证码保存在缓存中,只保存1-2分钟
缓存使用的是:ExpiringMap(一个轻量的Java缓存方式)
- <dependency>
- <groupId>net.jodahgroupId>
- <artifactId>expiringmapartifactId>
- <version>0.5.8version>
- dependency>
验证码的工具类:
- import java.awt.Color;
- import java.awt.Font;
- import java.awt.Graphics2D;
- import java.awt.image.BufferedImage;
- import java.util.Random;
-
-
- /*对图片进行处理的类和方法*/
- public class VerifyCode {
-
- public static String drawRandomText(int width,int height, BufferedImage verifyImg) {
-
- Graphics2D graphics = (Graphics2D)verifyImg.getGraphics();
-
- graphics.setColor(Color.WHITE);//设置画笔颜色-验证码背景色
-
- graphics.fillRect(0, 0, width, height);//填充背景
-
- graphics.setFont(new Font("微软雅黑", Font.BOLD, 40));
-
- // //数字和大小写字母的组合
- // String baseNumLetter= "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
-
- //数字和小写字母的组合
- String baseNumLetter= "123456789abcdefghijklmnopqrstuvwxyz";
-
- // //纯数字组合
- // String baseNumLetter= "123456789";
-
- StringBuffer sBuffer = new StringBuffer();
-
- int x = 10; //旋转原点的 x 坐标
-
- String ch = "";
-
- Random random = new Random();
-
- for(int i = 0;i < 4;i++){
-
- graphics.setColor(getRandomColor());
-
- //设置字体旋转角度
-
- int degree = random.nextInt() % 20; //角度小于20度
-
- int dot = random.nextInt(baseNumLetter.length());
-
- ch = baseNumLetter.charAt(dot) + "";
-
- sBuffer.append(ch);
-
- //正向旋转
-
- graphics.rotate(degree * Math.PI / 180, x, 45);
-
- graphics.drawString(ch, x, 45);
-
- //反向旋转
-
- graphics.rotate(-degree * Math.PI / 180, x, 45);
-
- x += 48;
-
- }
-
- //画干扰线
-
- for (int i = 0; i <3; i++) {
-
- // 设置随机颜色
-
- graphics.setColor(getRandomColor());
-
- // 随机画线
-
- graphics.drawLine(random.nextInt(width), random.nextInt(height),
-
- random.nextInt(width), random.nextInt(height));
-
- }
-
- //添加噪点
- for(int i=0;i<20;i++){
-
- int x1 = random.nextInt(width);
-
- int y1 = random.nextInt(height);
-
- graphics.setColor(getRandomColor());
-
- graphics.fillRect(x1, y1, 2,2);
-
- }
-
- return sBuffer.toString();
-
- }
-
- /**
- * 随机取色
- */
-
- private static Color getRandomColor() {
-
- Random ran = new Random();
-
- Color color = new Color(ran.nextInt(256),
-
- ran.nextInt(256), ran.nextInt(256));
-
- return color;
-
- }
-
- }
验证码接口:
- import com.sws.nlflow.portal.util.ExpiringMap;
- import com.sws.nlflow.portal.util.VerifyCode;
- import java.awt.image.BufferedImage;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.util.List;
- import javax.imageio.ImageIO;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
-
- /**
- * 验证码处理接口
- */
- @Slf4j
- @Controller
- @RequestMapping("/api")
- public class VerifyCodeController {
-
-
- @RequestMapping("/getVerifyCode")
- public void getVerificationCode(HttpServletResponse response, HttpServletRequest request) {
-
- try {
-
- int width = 200;
-
- int height = 69;
-
- BufferedImage verifyImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
-
- //生成对应宽高的初始图片
- //功能是生成验证码字符并加上噪点,干扰线,返回值为验证码字符
- String randomText = VerifyCode.drawRandomText(width, height, verifyImg);
-
- // request.getSession().setAttribute("verifyCode", randomText);
-
- //获取ExpiringMap,将验证码保存在此处
- net.jodah.expiringmap.ExpiringMap
VerifyCodemap = ExpiringMap.map; - VerifyCodemap.put(randomText, randomText);
-
- response.setContentType("image/png");//必须设置响应内容类型为图片,否则前台不识别
-
- OutputStream os = response.getOutputStream(); //获取文件输出流
-
- ImageIO.write(verifyImg, "png", os);//输出图片流
-
- os.flush();
-
- os.close();//关闭流
-
- } catch (IOException e) {
-
- log.error(e.getMessage());
-
- e.printStackTrace();
-
- }
-
- }
-
- }
缓存工具类:
- import java.io.Serializable;
- import java.util.concurrent.TimeUnit;
- import lombok.extern.slf4j.Slf4j;
- import net.jodah.expiringmap.ExpirationPolicy;
-
- /**
- * @author qushen
- * @create 2022/8/16 10:37
- */
- @Slf4j
- public class ExpiringMap implements Serializable {
-
- /**
- *
- * maxSize:map的最大长度,添加第1001个entry时,会导致第1个马上过期(即使没到过期时间)
- * expiration:过期时间和过期单位,设置过期时间,则永久有效.
- * expirationPolicy:过期策略的使用
- * CREATED: 在每次更新元素时,过期倒计时清零
- * ACCESSED: 在每次访问元素时,过期倒计时清零
- *
- * variableExpiration:允许更新过期时间值,如果不设置variableExpiration
- * 不允许更改过期时间,一旦执行更改过期时间的操作则会抛出UnsupportedOperationException异常
- * expirationListener:同步过期提醒
- * asyncExpirationListener:异步过期提醒
- * entryLoader:懒加载,调用get方法时若key不存在创建默认value
- *
- */
-
- public static net.jodah.expiringmap.ExpiringMap
map = net.jodah.expiringmap.ExpiringMap.builder() - //设置过期时间
- .expiration(120, TimeUnit.SECONDS)
- //设置过期协议
- .expirationPolicy(ExpirationPolicy.ACCESSED)
- .variableExpiration()
- .build();
-
- }
-
登录时候的验证方法:
-
- //传入参数: VerifyCode
-
- net.jodah.expiringmap.ExpiringMap
VerifyCodemap = ExpiringMap.map; -
-
-
- if(!VerifyCodemap.containsKey(VerifyCode)){
-
- return new Response(Integer.valueOf(1), "验证码不正确!");
- }