龙空技术网

我是怎样完成开源系统中的验证码的功能的?

架构师之道 471

前言:

今天朋友们对“csehtmlvalidator”大概比较关切,各位老铁们都需要剖析一些“csehtmlvalidator”的相关资讯。那么小编同时在网络上收集了一些关于“csehtmlvalidator””的相关资讯,希望看官们能喜欢,同学们一起来学习一下吧!

写在前面:

最近有一个想法,做一个程序员师徒系统。因为在大学期间的我在学习java的时候非常地迷茫,找不到自己的方向,也没有一个社会上有经验的前辈去指导,所以走了很多的弯路。后来工作了,想把自己的避坑经验分享给别人,但是发现身边都是有经验的开发者,也没有机会去分享自己的想法,所以富贵同学就想做一个程序员专属的师徒系统,秉承着徒弟能够有人指教少走弯路,师傅能桃李满天下的目的,所以开始做这个师徒系统,也会同步更新该系统所用到的技术,并且作为教程分享给大家,希望大家能够关注一波。

这里推荐使用gitee.com/ele-admin/E… 作为工具来实现验证码的功能,因为它好用,简单,可以作为系统的验证模块使用

第一步,导入jar包

sql复制代码		 <!--Redis-->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-data-redis</artifactId>        </dependency>        <!--Redis-->          <!--验证码-->        <dependency>            <groupId>com.github.whvcse</groupId>            <artifactId>easy-captcha</artifactId>            <version>1.6.2</version>        </dependency>        <!--验证码-->

之所以用redis的原因是用来存储验证码

第二步,编写redis配置文件

sql复制代码package com.wangfugui.apprentice.common.util;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.data.redis.core.ValueOperations;import org.springframework.stereotype.Component;import java.io.Serializable;import java.util.concurrent.TimeUnit;/** * RedisUtils:redis工具类 */@Componentpublic class RedisUtils {    @Autowired    @Qualifier("getRedisTemplate")    private RedisTemplate redisTemplate;    @Autowired    @Qualifier("getStringRedisTemplate")    private StringRedisTemplate stringRedisTemplate;    /**     * 设置键值     *     * @Param: [key, value]     * @return: boolean     * @Author: MaSiyi     * @Date: 2021/11/20     */    public boolean set(final String key, Object value) {        boolean result = false;        try {            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();            operations.set(key, value);            result = true;        } catch (Exception e) {            e.printStackTrace();        }        return result;    }    /**     * 设置键值(string)     *     * @Param: [key, value]     * @return: boolean     * @Author: MaSiyi     * @Date: 2021/11/20     */    public boolean setStr(final String key, String value) {        boolean result = false;        try {            ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();            operations.set(key, value);            result = true;        } catch (Exception e) {            e.printStackTrace();        }        return result;    }    /**     * 设置键值(string)     *     * @Param: [key, value]     * @return: boolean     * @Author: MaSiyi     * @Date: 2021/11/20     */    public boolean setStrEx(final String key, String value,long timeout, TimeUnit unit) {        boolean result = false;        try {            stringRedisTemplate.opsForValue().set(key, value, timeout, unit);            result = true;        } catch (Exception e) {            e.printStackTrace();        }        return result;    }    /**     * 写入缓存设置失效时间     *     * @param key     * @param value     * @return     */    public boolean setEx(final String key, Object value, Long expireTime) {        boolean result = false;        try {            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();            operations.set(key, value);            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);            result = true;        } catch (Exception e) {            e.printStackTrace();        }        return result;    }    /**     * 设置key-value     * <p>     * 注: 若已存在相同的key, 那么原来的key-value会被丢弃     *     * @param key     key     * @param value   key对应的value     * @param timeout 过时时长     * @param unit    timeout的单位     * @date 2020/3/8 15:40:59     */    public void setEx(String key, String value, long timeout, TimeUnit unit) {        redisTemplate.opsForValue().set(key, value, timeout, unit);    }    /**     * 批量删除对应的value     */    public void remove(final String... keys) {        for (String key : keys) {            remove(key);        }    }    /**     * 删除对应的value     */    public void remove(final String key) {        if (exists(key)) {            redisTemplate.delete(key);        }    }    /**     * 判断缓存当中是否有对应的value     *     * @param key     * @return     */    public boolean exists(final String key) {        return redisTemplate.hasKey(key);    }    /**     * 根据key,获取到对应的value值     *     * @param key key-value对应的key     * @return 该key对应的值。     * 注: 若key不存在, 则返回null。     */    public Object get(String key) {        return redisTemplate.opsForValue().get(key);    }    /**     * 根据key,获取到对应的value(string)值     *     * @param key key-value对应的key     * @return 该key对应的值。     * 注: 若key不存在, 则返回null。     */    public String getStr(String key) {        return stringRedisTemplate.opsForValue().get(key);    }}

这里注入两个模板的原因是用来区分string类型和object的值

第三步,编写配置类

sql复制代码package com.wangfugui.apprentice.config;import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;import com.fasterxml.jackson.annotation.JsonAutoDetect;import com.fasterxml.jackson.annotation.JsonTypeInfo;import com.fasterxml.jackson.annotation.PropertyAccessor;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.data.redis.serializer.StringRedisSerializer;@Configurationpublic class RedisConfig {    /**     * 重写Redis序列化方式,使用Json方式: * 当我们的数据存储到Redis的时候,我们的键(key)和值(value)     * 都是通过Spring提供的Serializer序列化到数据库的。RedisTemplate默认使用的是JdkSerializationRedisSerializer,     * StringRedisTemplate默认使用的是StringRedisSerializer。     * Spring Data JPA为我们提供了下面的Serializer:     * GenericToStringSerializer、Jackson2JsonRedisSerializer、JacksonJsonRedisSerializer、     * JdkSerializationRedisSerializer、OxmSerializer、StringRedisSerializer。     * 在此我们将自己配置RedisTemplate并定义Serializer。     *     * @param redisConnectionFactory * @return     */    @Bean("getRedisTemplate")    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();        /**         * 配置连接工厂         */        redisTemplate.setConnectionFactory(redisConnectionFactory);        /**         * 使用FJackson2JsonRedisSerializer序列化工具         */        FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);        ObjectMapper objectMapper = new ObjectMapper();        /**         * 指定要序列化的域Field、set、get,以及修饰符范围         * ANY是都有,包括private、public         */        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);        /**         * 指定序列化输入的类型,类必须是非final修饰的,         * final修饰的类,比如         * public final class User implements Serializable{},会包异常         */        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,                ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);        /**         *设置键(key)的序列化采用StringRedisSerializer。         */        redisTemplate.setKeySerializer(new StringRedisSerializer());        redisTemplate.setHashKeySerializer(new StringRedisSerializer());        /**         * 设置值(value)的序列化采用jackson2JsonRedisSerializer。         */        redisTemplate.setValueSerializer(fastJsonRedisSerializer);        redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);        redisTemplate.afterPropertiesSet();        return redisTemplate;    }    /**     * 配置stringRedisTemplate序列化方式     *     * @param redisConnectionFactory     * @return     */    @Bean("getStringRedisTemplate")    @ConditionalOnMissingBean(StringRedisTemplate.class)    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {        StringRedisTemplate template = new StringRedisTemplate();        template.setConnectionFactory(redisConnectionFactory);        return template;    }}

配置类这里设置了两个模板,分别对应了第二步的模板需求

第四步,编写controller类

sql复制代码package com.wangfugui.apprentice.controller;import com.wangfugui.apprentice.common.util.RedisUtils;import com.wangfugui.apprentice.common.util.ResponseUtils;import com.wf.captcha.SpecCaptcha;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;import java.util.UUID;import java.util.concurrent.TimeUnit;@Api(tags = "验证码")@RestController@RequestMapping("captcha")public class CaptchaController {    @Autowired    private RedisUtils redisUtil;        @ResponseBody    @ApiOperation("生成验证码")    @GetMapping("/makeCaptcha")    public ResponseUtils makeCaptcha() {        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 5);        String verCode = specCaptcha.text().toLowerCase();        String key = UUID.randomUUID().toString();        // 存入redis并设置过期时间为30分钟        redisUtil.setStrEx(key, verCode, 30, TimeUnit.MINUTES);        // 将key和base64返回给前端        HashMap<String, Object> map = new HashMap<>();        map.put("key", key);        map.put("image", specCaptcha.toBase64());        return ResponseUtils.success(map);    }        @ResponseBody    @ApiOperation("校验验证码")    @PostMapping("/getCaptcha")    public ResponseUtils getCaptcha(String verCode,String verKey){        // 获取redis中的验证码        String redisCode = redisUtil.getStr(verKey);        // 判断验证码        if (verCode==null || !redisCode.equals(verCode.trim().toLowerCase())) {            return ResponseUtils.error("验证码不正确");        }        return ResponseUtils.success("验证成功");    }  }

之后测试就行啦,生成样式举例:

作者:掉头发的王富贵

链接:

标签: #csehtmlvalidator