4.还需要加入配置类,否则启动不起来,一样@component注解不要忘记加!
```package com.laoyang.educms.config;
/**
- @author:Kevin
- @create: 2022-10-05 15:38
- @Description:
*/
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.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
@Component
public class Config {
@Bean(name = "template")
public RedisTemplate<String, Object> template(RedisConnectionFactory factory) {
// 创建RedisTemplate<String, Object>对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 配置连接工厂
template.setConnectionFactory(factory);
// 定义Jackson2JsonRedisSerializer序列化对象
Jackson2JsonRedisSerializer<Object> jacksonSeial = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会报异常
om.activateDefaultTyping(
LaissezFaireSubTypeValidator.instance ,
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.WRAPPER_ARRAY);
jacksonSeial.setObjectMapper(om);
StringRedisSerializer stringSerial = new StringRedisSerializer();
// redis key 序列化方式使用stringSerial
template.setKeySerializer(stringSerial);
// redis value 序列化方式使用jackson
template.setValueSerializer(jacksonSeial);
// redis hash key 序列化方式使用stringSerial
template.setHashKeySerializer(stringSerial);
// redis hash value 序列化方式使用jackson
template.setHashValueSerializer(jacksonSeial);
template.afterPropertiesSet();
return template;
}
}
5.创建service:验证码service:两个方法,一个是生成验证码图片,另一个方法是验证输入的验证码是否正确。
```package com.laoyang.educms.service;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author:Kevin
* @create: 2022-10-05 13:50
* @Description: 验证码
*/
public interface ValidateCodeService {
/**
* 生成验证码
*/
void create(String key, HttpServletResponse response) throws IOException;
/**
* 校验验证码
* @param key 前端上送 key
* @param value 前端上送待校验值
*/
boolean check(String key, String value);
}
6.编写验证码service的实现类:注意这里会用到缓存,因为咱们这个redis工具类不是static的,所以这里用的话需要对象注入调用
```package com.laoyang.educms.service.impl;
import com.laoyang.CommonUtils.Contst.ResultCode;
import com.laoyang.MyException;
import com.laoyang.educms.entity.CacheObject;
import com.laoyang.educms.service.ValidateCodeService;
import com.laoyang.educms.utils.redisutils;
import com.wf.captcha.ArithmeticCaptcha;
import com.wf.captcha.base.Captcha;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
- @author:Kevin
- @create: 2022-10-05 13:51
@Description:
*/
@Service
public class ValidateCodeServiceImpl implements ValidateCodeService {@Autowired
private redisutils redisutils;/**
- 生成验证码图片
- @param key
- @param response
@throws IOException
*/
@Override
public void create(String key, HttpServletResponse response) throws IOException {
if (StringUtils.isBlank(key)) {throw new MyException(ResultCode.ERROR,"验证码不能为空");
}
response.setContentType(MediaType.IMAGE_PNG_VALUE);
response.setHeader(HttpHeaders.PRAGMA, "No-cache");
response.setHeader(HttpHeaders.CACHE_CONTROL, "No-cache");
response.setDateHeader(HttpHeaders.EXPIRES, 0L);Captcha captcha = new ArithmeticCaptcha(115, 42);
captcha.setCharType(2);String text = captcha.text();
System.out.println(text);//设置过期时间为5分种
redisutils.set(key,text,300);captcha.out(response.getOutputStream());
}
/**
- 校验输入的验证码
- @param key 前端上送 key
- @param value 前端上送待校验值
@return
*/
@Override
public boolean check(String key, String value) {
if (StringUtils.isBlank(value)) {throw new MyException(ResultCode.ERROR,"验证码不能为空");
}
//根据key从缓存中获取验证码
String code = (String) redisutils.get(key);
if (code == null) {throw new MyException(ResultCode.ERROR,"验证码已经过期");
}
//比对验证码
if (!StringUtils.equalsIgnoreCase(value,code)) { throw new MyException(ResultCode.ERROR,"验证码不正确");
}
//验证通过,立即从缓存中删除验证码
redisutils.del(key);
return true;}
}
```