图片码生成

    xiaoxiao2023-11-07  161

    1.项目结构

    2.类的内容

    2.1 Digest

    package com.rtsm.zhjs.background.common.imgcode; /** * @author loki * @date 2018-04-27 上午10:16 **/ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.security.MessageDigest; public class Digest { private static final Logger logger = LoggerFactory.getLogger(Digest.class); protected String algorithm; public Digest(String alg) { this.algorithm = alg; } public byte[] encode2bytes(byte[] bytes) { try { MessageDigest md = MessageDigest.getInstance(this.algorithm); return md.digest(bytes); } catch (Exception var3) { logger.error("MessageDigest with {} fail", this.algorithm); logger.error("MessageDigest fail", var3); return null; } } public byte[] encode2bytes(String data, String charset) { if (data == null) { return null; } else { try { byte[] bytes; if (charset == null) { bytes = data.getBytes(); } else { bytes = data.getBytes(charset); } return this.encode2bytes(bytes); } catch (Exception var4) { logger.error("MD5 encode fail", var4); return null; } } } public String encode(String data, String charset, boolean lowercase) { byte[] endata = this.encode2bytes(data, charset); return endata == null ? null : HexCode.encode(endata, lowercase); } public String encode(String data, boolean lowercase) { return this.encode(data, (String) null, lowercase); } public String encode(String data) { return this.encode(data, (String) null, true); } public String encode(String data, String charset) { return this.encode(data, charset, true); } }

    2.2 HexCode

    package com.rtsm.zhjs.background.common.imgcode; /** * @author loki * @date 2018-04-27 上午10:18 **/ public class HexCode { private static final char[] UPPER_HEX_CHARS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; private static final char[] LOWER_HEX_CHARS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; public HexCode() { } public static char[] encode2char(byte[] bytes, boolean lowercase) { char[] chars = new char[bytes.length * 2]; for (int i = 0; i < chars.length; i += 2) { byte b = bytes[i / 2]; char[] HEX_CHARS = LOWER_HEX_CHARS; if (!lowercase) { HEX_CHARS = UPPER_HEX_CHARS; } chars[i] = HEX_CHARS[b >>> 4 & 15]; chars[i + 1] = HEX_CHARS[b & 15]; } return chars; } public static String encode(byte[] bytes, boolean lowercase) { char[] endata = encode2char(bytes, lowercase); return new String(endata); } public static byte[] decode(String data) { int len = (data.length() + 1) / 2; byte[] bytes = new byte[len]; int index = 0; for (int i = 1; i < data.length(); i += 2) { char h = data.charAt(i - 1); char l = data.charAt(i); bytes[index] = decodeByte(h, l); ++index; } return bytes; } public static byte decodeByte(char hight, char low) { int value; byte data; if (hight >= 65 && hight <= 70) { value = hight - 65 + 10; data = (byte) (value << 4); } else if (hight >= 97 && hight <= 102) { value = hight - 97 + 10; data = (byte) (value << 4); } else { if (hight < 48 || hight > 57) { throw new RuntimeException(); } value = hight - 48; data = (byte) (value << 4); } if (low >= 65 && low <= 70) { value = low - 65 + 10; data |= (byte) value; } else if (low >= 97 && low <= 102) { value = low - 97 + 10; data |= (byte) value; } else { if (low < 48 || low > 57) { throw new RuntimeException(); } value = low - 48; data |= (byte) value; } return data; } }

    2.3 ImageCode

    package com.rtsm.zhjs.background.common.imgcode; /** * 图形验证码对象 * * @author loki * @date 2018-04-27 上午10:12 **/ public class ImgCode { private String key; private String code; private int width = -1; private int height = -1; private String type = "png"; private int expired = 3600;//默认600s public ImgCode(String code) { this.code = code; } public ImgCode(String key, String code) { super(); this.key = key; this.code = code; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int higth) { this.height = higth; } public String getType() { return type; } public void setType(String type) { this.type = type; } public int getExpired() { return expired; } public void setExpired(int expired) { this.expired = expired; } }

    2.4 ImgWritter.java

    2.4.1 ImageWritter

    package com.rtsm.zhjs.background.common.imgcode; import com.github.bingoohuang.patchca.background.MyCustomBackgroundFactory; import com.github.bingoohuang.patchca.color.ColorFactory; import com.github.bingoohuang.patchca.custom.ConfigurableCaptchaService; import com.github.bingoohuang.patchca.filter.AbstractFilterFactory; import com.github.bingoohuang.patchca.filter.FilterFactory; import com.github.bingoohuang.patchca.filter.library.CurvesImageOp; import com.github.bingoohuang.patchca.filter.library.MarbleImageOp; import com.github.bingoohuang.patchca.filter.library.RippleImageOp; import com.github.bingoohuang.patchca.font.RandomFontFactory; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * 图片验证码的绘制处理 * @author loki * @date 下午3:48 2018/5/4 **/ @Slf4j public class ImgWritter { //验证码是否添加干扰点配置项,不配置默认为true public static final String CONF_USE_INTERFERENCE = "true"; private static final String IMG_WIDTH="160"; private static final String IMG_HEIGHT="70"; private static final String IMG_FONT_SIZE="48"; // 初始化图片验证码的主体类 private static ConfigurableCaptchaService cs = new ConfigurableCaptchaService(); private static Random random = new Random(); static { // 设置color的生成器 cs.setColorFactory(new ColorFactory() { @Override public Color getColor(int x) { int[] c = new int[3]; int i = random.nextInt(c.length); for (int fi = 0; fi < c.length; fi++) { if (fi == i) { c[fi] = random.nextInt(71); } else { c[fi] = random.nextInt(256); } } return new Color(c[0], c[1], c[2]); } }); // 设置图片的绘制器 cs.setFilterFactory((FilterFactory) new SimpleRippleFilterFactory(cs.getColorFactory())); // 设置验证码的背景 cs.setBackgroundFactory(new MyCustomBackgroundFactory()); // 获取图片的宽度 String strWidth =IMG_WIDTH; if (StringUtils.isNumeric(strWidth)) { cs.setWidth(Integer.parseInt(strWidth)); } // 获取图片的高度 String strHeigth = IMG_HEIGHT; if (StringUtils.isNumeric(strHeigth)) { cs.setHeight(Integer.parseInt(strHeigth)); } // 设置图片字体的大小 String strFontSize = IMG_FONT_SIZE; if (StringUtils.isNumeric(strFontSize)) { if (cs.getFontFactory() instanceof RandomFontFactory) { RandomFontFactory fontFactory = (RandomFontFactory) cs.getFontFactory(); fontFactory.setMinSize(Integer.parseInt(strFontSize)); fontFactory.setMaxSize(Integer.parseInt(strFontSize)); } } } /** * 图片验证码的响应头部,设置无缓存模式 * * @param imgCode * @param response */ public static void responseHeader(ImgCode imgCode, HttpServletResponse response) { response.setContentType("image/" + imgCode.getType()); response.setHeader("Cache-Control", "no-cache, no-store"); response.setHeader("Pragma", "no-cache"); long time = System.currentTimeMillis(); response.setDateHeader("Last-Modified", time); response.setDateHeader("Date", time); response.setDateHeader("Expires", time); } /** * 响应回写图片验证码内容 * * @param imgCode * @param response */ public static void responseImg(ImgCode imgCode, HttpServletResponse response) { try { int width = imgCode.getWidth(); int height = imgCode.getHeight(); if (width < 0) { width = cs.getWidth(); } if (height < 0) { height = cs.getHeight(); } BufferedImage bufImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); // 填充背景 cs.getBackgroundFactory().fillBackground(bufImage); cs.getFontFactory().setWord(imgCode.getCode()); // 绘制验证码 cs.getTextRenderer().draw(imgCode.getCode(), bufImage, cs.getFontFactory(), cs.getColorFactory()); // 进行模糊扭曲处理 bufImage = cs.getFilterFactory().applyFilters(bufImage); Graphics g = bufImage.getGraphics(); if (!"false".equalsIgnoreCase(CONF_USE_INTERFERENCE)) { // 绘制干扰点 for (int i = 0; i < 3 * height; i++) { g.setColor(cs.getColorFactory().getColor(i)); int x = random.nextInt(width); int y = random.nextInt(height); g.drawOval(x, y, 0, 0); } } g.dispose(); // 响应图片 ImageIO.write(bufImage, imgCode.getType(), response.getOutputStream()); } catch (Exception e) { log.error("create image code stream fail", e); } } } class SimpleRippleFilterFactory extends AbstractFilterFactory { public static final String CONF_USE_RIPPLE = "false"; public static final String CONF_USE_MARBLE = "false"; public static final String CONF_USE_CURVES = "false"; protected List<BufferedImageOp> filters; // 波浪扭曲处理 protected RippleImageOp ripple = new RippleImageOp(); // 模糊处理 protected MarbleImageOp marble = new MarbleImageOp(); // 曲线处理 protected CurvesImageOp curves = new CurvesImageOp(); public void setColorFactory(ColorFactory colorFactory) { curves.setColorFactory(colorFactory); } public SimpleRippleFilterFactory(ColorFactory colorFactory) { setColorFactory(colorFactory); } protected List<BufferedImageOp> getPreRippleFilters() { List<BufferedImageOp> list = new ArrayList<BufferedImageOp>(); // 检查图片验证码的模糊扭曲处理是否配置,如果配置了则设置相应的处理方式 // 验证码以波浪形式变形,默认不配置则为false if ("true".equalsIgnoreCase(CONF_USE_RIPPLE)) { list.add(ripple); } // 验证码模糊处理,默认不配置则为false if ("true".equalsIgnoreCase(CONF_USE_MARBLE)) { list.add(marble); } // //验证码是否加一条曲线,默认不配置则为false if ("true".equalsIgnoreCase(CONF_USE_CURVES)) { list.add(curves); } return list; } protected List<BufferedImageOp> getPostRippleFilters() { return new ArrayList<BufferedImageOp>(); } @Override public List<BufferedImageOp> getFilters() { if (filters == null) { filters = new ArrayList<BufferedImageOp>(); filters.addAll(getPreRippleFilters()); filters.addAll(getPostRippleFilters()); } return filters; } }

    2.4.2 

    SimpleRippleFilterFactory package com.rtsm.zhjs.background.common.imgcode; import com.github.bingoohuang.patchca.background.MyCustomBackgroundFactory; import com.github.bingoohuang.patchca.color.ColorFactory; import com.github.bingoohuang.patchca.custom.ConfigurableCaptchaService; import com.github.bingoohuang.patchca.filter.AbstractFilterFactory; import com.github.bingoohuang.patchca.filter.FilterFactory; import com.github.bingoohuang.patchca.filter.library.CurvesImageOp; import com.github.bingoohuang.patchca.filter.library.MarbleImageOp; import com.github.bingoohuang.patchca.filter.library.RippleImageOp; import com.github.bingoohuang.patchca.font.RandomFontFactory; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * 图片验证码的绘制处理 * @author loki * @date 下午3:48 2018/5/4 **/ @Slf4j public class ImgWritter { //验证码是否添加干扰点配置项,不配置默认为true public static final String CONF_USE_INTERFERENCE = "true"; private static final String IMG_WIDTH="160"; private static final String IMG_HEIGHT="70"; private static final String IMG_FONT_SIZE="48"; // 初始化图片验证码的主体类 private static ConfigurableCaptchaService cs = new ConfigurableCaptchaService(); private static Random random = new Random(); static { // 设置color的生成器 cs.setColorFactory(new ColorFactory() { @Override public Color getColor(int x) { int[] c = new int[3]; int i = random.nextInt(c.length); for (int fi = 0; fi < c.length; fi++) { if (fi == i) { c[fi] = random.nextInt(71); } else { c[fi] = random.nextInt(256); } } return new Color(c[0], c[1], c[2]); } }); // 设置图片的绘制器 cs.setFilterFactory((FilterFactory) new SimpleRippleFilterFactory(cs.getColorFactory())); // 设置验证码的背景 cs.setBackgroundFactory(new MyCustomBackgroundFactory()); // 获取图片的宽度 String strWidth =IMG_WIDTH; if (StringUtils.isNumeric(strWidth)) { cs.setWidth(Integer.parseInt(strWidth)); } // 获取图片的高度 String strHeigth = IMG_HEIGHT; if (StringUtils.isNumeric(strHeigth)) { cs.setHeight(Integer.parseInt(strHeigth)); } // 设置图片字体的大小 String strFontSize = IMG_FONT_SIZE; if (StringUtils.isNumeric(strFontSize)) { if (cs.getFontFactory() instanceof RandomFontFactory) { RandomFontFactory fontFactory = (RandomFontFactory) cs.getFontFactory(); fontFactory.setMinSize(Integer.parseInt(strFontSize)); fontFactory.setMaxSize(Integer.parseInt(strFontSize)); } } } /** * 图片验证码的响应头部,设置无缓存模式 * * @param imgCode * @param response */ public static void responseHeader(ImgCode imgCode, HttpServletResponse response) { response.setContentType("image/" + imgCode.getType()); response.setHeader("Cache-Control", "no-cache, no-store"); response.setHeader("Pragma", "no-cache"); long time = System.currentTimeMillis(); response.setDateHeader("Last-Modified", time); response.setDateHeader("Date", time); response.setDateHeader("Expires", time); } /** * 响应回写图片验证码内容 * * @param imgCode * @param response */ public static void responseImg(ImgCode imgCode, HttpServletResponse response) { try { int width = imgCode.getWidth(); int height = imgCode.getHeight(); if (width < 0) { width = cs.getWidth(); } if (height < 0) { height = cs.getHeight(); } BufferedImage bufImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); // 填充背景 cs.getBackgroundFactory().fillBackground(bufImage); cs.getFontFactory().setWord(imgCode.getCode()); // 绘制验证码 cs.getTextRenderer().draw(imgCode.getCode(), bufImage, cs.getFontFactory(), cs.getColorFactory()); // 进行模糊扭曲处理 bufImage = cs.getFilterFactory().applyFilters(bufImage); Graphics g = bufImage.getGraphics(); if (!"false".equalsIgnoreCase(CONF_USE_INTERFERENCE)) { // 绘制干扰点 for (int i = 0; i < 3 * height; i++) { g.setColor(cs.getColorFactory().getColor(i)); int x = random.nextInt(width); int y = random.nextInt(height); g.drawOval(x, y, 0, 0); } } g.dispose(); // 响应图片 ImageIO.write(bufImage, imgCode.getType(), response.getOutputStream()); } catch (Exception e) { log.error("create image code stream fail", e); } } } class SimpleRippleFilterFactory extends AbstractFilterFactory { public static final String CONF_USE_RIPPLE = "false"; public static final String CONF_USE_MARBLE = "false"; public static final String CONF_USE_CURVES = "false"; protected List<BufferedImageOp> filters; // 波浪扭曲处理 protected RippleImageOp ripple = new RippleImageOp(); // 模糊处理 protected MarbleImageOp marble = new MarbleImageOp(); // 曲线处理 protected CurvesImageOp curves = new CurvesImageOp(); public void setColorFactory(ColorFactory colorFactory) { curves.setColorFactory(colorFactory); } public SimpleRippleFilterFactory(ColorFactory colorFactory) { setColorFactory(colorFactory); } protected List<BufferedImageOp> getPreRippleFilters() { List<BufferedImageOp> list = new ArrayList<BufferedImageOp>(); // 检查图片验证码的模糊扭曲处理是否配置,如果配置了则设置相应的处理方式 // 验证码以波浪形式变形,默认不配置则为false if ("true".equalsIgnoreCase(CONF_USE_RIPPLE)) { list.add(ripple); } // 验证码模糊处理,默认不配置则为false if ("true".equalsIgnoreCase(CONF_USE_MARBLE)) { list.add(marble); } // //验证码是否加一条曲线,默认不配置则为false if ("true".equalsIgnoreCase(CONF_USE_CURVES)) { list.add(curves); } return list; } protected List<BufferedImageOp> getPostRippleFilters() { return new ArrayList<BufferedImageOp>(); } @Override public List<BufferedImageOp> getFilters() { if (filters == null) { filters = new ArrayList<BufferedImageOp>(); filters.addAll(getPreRippleFilters()); filters.addAll(getPostRippleFilters()); } return filters; } }

    2.5 Md5

    package com.rtsm.zhjs.background.common.imgcode; /** * @author loki * @date 2018-04-27 上午10:15 **/ public class Md5 { private static final Digest digest = new Digest("MD5"); public Md5() { } public static byte[] encode2bytes(byte[] bytes) { return digest.encode2bytes(bytes); } public static byte[] encode2bytes(String data, String charset) { return digest.encode2bytes(data, charset); } public static String encode(String data, String charset, boolean lowercase) { return digest.encode(data, charset, lowercase); } public static String encode(String data, boolean lowercase) { return encode(data, (String) null, lowercase); } public static String encode(String data) { return encode(data, (String) null, true); } public static String encode(String data, String charset) { return encode(data, charset, true); } }

    3. ImgCodeService

    package com.rtsm.zhjs.background.modules.system.service; import com.ace.cache.EnableAceCache; import com.ace.cache.service.IRedisService; import com.rtsm.zhjs.background.common.imgcode.ImgCode; import com.rtsm.zhjs.background.common.imgcode.Md5; import com.rtsm.zhjs.background.util.MapUtils; import com.rtsm.zhjs.background.util.UUIDUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; import java.util.Map; /** * @author loki * @date 2018-04-27 上午10:09 **/ @PropertySource({"classpath:application.yml"}) @Component @EnableAceCache @Slf4j public class ImgCodeService { // 配置文件未配置时默认使用的验证码列表 private static String[] DEFAULT_CHARS = {"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "P", "Q", "R", "S", "T", "U", "W", "X", "Y", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "k", "m", "p", "q", "r", "s", "t", "u", "w", "x", "y"}; private static final String IMG_SIGN_KEY = "1f905d35378e4a5d89aeb126faf8baf9"; private static final String IMG_CACHE_KEY_PREFFIX = "imgcode_"; private static final int IMG_CODE_EXPIRED = 36000;//二维码过期时间 默认为10分钟 private static String[] IMG_CHARS; @Autowired private IRedisService iRedisService; /** * 获取验证码字符集列表,这里只生成数字加英文(不区分大小写) * * @return */ private String[] getImgCodeChars() { if (IMG_CHARS != null) { return IMG_CHARS; } return DEFAULT_CHARS; } /** * 生成图片验证码内容 * * @return */ public String generateImgCode(int length) { if (length < 0) { log.info("图形验证码长度不能为0"); } String[] verifyCodes = getImgCodeChars(); StringBuilder sb = new StringBuilder(length); int rand; // Random random = new Random(); // 随机生成索引获取验证码字符 for (int i = 0; i < length; i++) { // rand = random.nextInt(length); rand = Integer.valueOf(String.valueOf(Math.round(Math.random() * (verifyCodes.length - 1)))); sb.append(verifyCodes[rand]); } return sb.toString(); } /** * 如果key存在则使用同一个key刷新验证码内容 * * @param key * @param value * @param expired * @return */ public boolean refreshImgCode(String key, String value, int expired) { if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) { if (iRedisService.exists(key)) { String result = iRedisService.set(key, value, expired); if (StringUtils.isNotBlank(result) && "OK".equals(result)) { return true; } } } return false; } /** * 保存验证码 * * @param key * @param value * @param expired * @return */ public String saveImgCode(String key, String value, int expired) { if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) { log.info("保存图形验证码"); return iRedisService.set(IMG_CACHE_KEY_PREFFIX + key, value, expired); } return ""; } /** * 生成图片验证码 * * @param length * @param client_ip * @return */ public ImgCode generate(int length, String client_ip, String existKey) { return generate(length, client_ip, IMG_CODE_EXPIRED, existKey); } /** * 生成图片验证码 * * @param length * @param client_ip * @param expired * @return */ public ImgCode generate(int length, String client_ip, int expired, String existKey) { // 生成验证码内容 String imgCode = generateImgCode(length); long time = System.currentTimeMillis(); // 拼接验证码缓存保存的内容,除验证码外还保存时间、IP、和签名 StringBuilder content = new StringBuilder(32); content.append("img_code=").append(imgCode).append("&time=").append(time).append("&ip=") .append(client_ip); String sign = Md5.encode(content.toString() + IMG_SIGN_KEY); content.append("&sign=").append(sign); String value = content.toString(); String key = existKey; // 如果key存在则刷新,不存在则添加 if (StringUtils.isBlank(key) || !refreshImgCode(key, value, expired)) { // uuid生成key key = UUIDUtils.generateUuid(); // 写入缓存,一定要有过期时间,建议验证码过期时间为10分钟 if (!"OK".equals(saveImgCode(key, value, expired))) { log.info("保存图形验证码失败"); } } // 返回 ImgCode imgInfo = new ImgCode(key, imgCode); imgInfo.setExpired(expired); return imgInfo; } /** * 检查验证码是否正确 * * @param imgInfo * @param client_ip * @return */ public boolean checkImgCode(ImgCode imgInfo, String client_ip, boolean isDel) { String key = IMG_CACHE_KEY_PREFFIX + imgInfo.getKey(); log.info("-------------key:" + key); // 获取缓存中的验证码 String strSvcInfo = iRedisService.get(key); if (StringUtils.isBlank(strSvcInfo)) { log.info("img key[{}] cache value is empty", key); return false; } // 检验签名,先截取sign之前的字段 int pos = strSvcInfo.lastIndexOf("&sign="); if (pos < 0) { log.info("img key[{}] cache value is empty", key); return false; } String subStr = strSvcInfo.substring(0, pos); String sign = Md5.encode(subStr + IMG_SIGN_KEY); if (!sign.equals(strSvcInfo.substring(pos + 6))) { log.info("img key[{}] cache value sign is invalid", key); return false; } // 获取缓存的数据,校验验证码是否正确 Map<String, String> imgSvcInfo = MapUtils.str2Map(strSvcInfo); String imgCode = imgSvcInfo.get("img_code"); if (!imgInfo.getCode().equalsIgnoreCase(imgCode)) { log.info("img key[{}] code incorrect.cache code={},request code={}", key, imgCode, imgInfo.getCode()); return false; } // 如果ip不为null,则验证ip是否正确,因为正常情况生成验证码和使用验证码应该是同一个IP请求 if (client_ip != null) { String ip = imgSvcInfo.get("ip"); if (!client_ip.equals(ip)) { log.error("img key[{}] ip incorrect", key); return false; } } // 验证成功后删除redis缓存的信息 if (!isDel) { return true; } iRedisService.del(key); return true; } }

    4.html图片码对应文件

    点击二维码的时候刷新

     

    5.js对应调用

    //从cookie中获取图片码,将后台请求图片接口的路径放入到html的src中即可,imageKey为后台往cookie中塞入的值 var imageKey = document.cookie;

    6.Controller中的代码

    /** * 获取图形验证码 * * @author loki * @date 11:24 PM 2019/3/20 **/ @GetMapping(value = "/imgCode/{imgk}") @ResponseBody public void getImageCode(HttpServletRequest request, HttpServletResponse response, @PathVariable String imgk) { ImgCode imgCode = sysYhxxService.getImgCode(ClientUtil.getClientIp(request), imgk); ImgWritter.responseHeader(imgCode, response); Cookie cookie = new Cookie("imgk",imgCode.getKey()); cookie.setMaxAge(imgCode.getExpired()); cookie.setPath("/"); response.addCookie(cookie); ImgWritter.responseImg(imgCode, response); }

    图片码生成了以后放入到cookie中了,所以在js中直接src(接口访问路径)就可以显示出图片码样式。

    存入redis中的imgk也可以在js中获取。

    当页面加载的时候就去Controller中获取图片码,并在js中获取imgk,请求登陆的时候传到Controller中,在从redis中根据key获取到对应的imgCode,校验用户输入的是否正确

     

    最新回复(0)