redis服务
这个模块主要负责进行一些数据校验,帮助我们实现用户的权限管理,用户的登录验证等功能。之后的一些数据一致也可以通过redis实现,暂时没写
(1)引入需要的依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>
redis需要重写序列化机制,不然可能会出现两边数据不一致的问题。可以用springboot自带的,也可以使用第三方的,这里我引入了ali的
(2) 编写配置文件
spring:
application:
name: redis-server-6721
redis:
jedis:
pool:
max-active: 5
password:
host: ******
port: 6379
database: 0
mail:
#密码需要自己申请
password: ******
host: smtp.qq.com
#发件人的邮箱
username: *******
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
server:
port: 6721
email:
text: 尊敬的用户您好,欢迎使用本产品,验证码有效期:5分钟,您的验证码为:
title: 测试用例
from: 971773196@qq.com
我的redis服务没有密码,如果有密码的话是需要进行配置的。
配置基本复制即可
我们还需要在代码中进行一些配置
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.nio.charset.Charset;
public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
public static final Charset DEFAULT_CHARSET=Charset.forName("UTF-8");
private Class<T> clazz;
public FastJsonRedisSerializer(Class<T> clazz) {
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException {
if(t==null){
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if(bytes == null || bytes.length<=0){
return null;
}
String str=new String(bytes,DEFAULT_CHARSET);
return (T)JSON.parseObject(str,clazz);
}
}
一些配置我也不是很懂,基本没什么需要改动的直接复制即可使用
@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
public class RedisConfig {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<Object,Object> template=new RedisTemplate<>();
FastJsonRedisSerializer fastJsonRedisSerializer=new FastJsonRedisSerializer(Object.class);
template.setValueSerializer(fastJsonRedisSerializer);
template.setHashValueSerializer(fastJsonRedisSerializer);
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean(StringRedisTemplate.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory){
StringRedisTemplate template=new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
这个也是复制即可,小编也不懂,但用了很多次,从来没改过也没出过问题。
(3) 编写工具类
@Component
public class RedisUtil {
@Resource
private RedisTemplate redisTemplate;
public boolean expire(String key,long time){
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 存值
* @param key
* @param value
* @return
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
109
* 普通缓存放入并设置时间
110
* @param key 键
111
* @param value 值
112
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
113
* @return true成功 false 失败
114
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public Object get(String key){
return redisTemplate.opsForValue().get(key);
}
/***
* 自增 用于登录验证
* @param key
* @return
*/
public boolean incr(String key){
if(null == get(key)){
set(key,1,5*60);
return true;
}
// if(get(key).equals("login")){
// return true;
// }
int count= (int) get(key);
if(count==5){
return false;
}else{
redisTemplate.opsForValue().increment(key,1);
return true;
}
}
public boolean deleteKey(String key){
try{
if(null == key){
return false;
}
return redisTemplate.delete(key);
}catch (Exception e){
e.printStackTrace();
}
return false;
}
}
@Component
public class EmailSend {
@Autowired
private JavaMailSender mailSender;
@Autowired
private RedisUtil redisUtil;
@Value("${email.from}")
private String emailFrom;
@Value("${email.text}")
private String emailText;
@Value(("${email.title}"))
private String emailTitle;
private SimpleMailMessage message=new SimpleMailMessage();
@Transactional
public boolean sendSimpleEmail(String emailTo){
try{
message.setFrom(emailFrom);
message.setTo(emailTo);
message.setSubject(emailTitle);
String code=generateCode();
message.setText(emailText+code);
mailSender.send(message);
redisUtil.set(emailTo,code,5*60);
}catch (Exception e){
e.printStackTrace();
return false;
}
return true;
}
private String generateCode(){
String msg="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
StringBuilder builder=new StringBuilder();
Random r=new Random();
for (int i = 0; i < 5; i++) {
int x=r.nextInt(36);
builder.append(msg.charAt(x));
}
return builder.toString();
}
}
这是我的一些工具类,大家可以自行添加,这里只有一些简单的存取和自增等。网上有很多类似的工具类,不需要自己编写太多,会用即可。
第二个发送验证码功能需要自己在QQ邮箱或者别的邮箱申请一个密钥,我设置了有效期为五分钟。大家可以根据自己的需求修改。
(4)编写控制层
由于只是简单的权限验证,我只编写了控制层,用于完成之前的一些需求。对于邮箱的验
@RestController
public class RedisController {
@Autowired
private RedisUtil redisUtil;
@GetMapping("/isLogin/{userId}")
public boolean isLogin(@PathVariable("userId") String userId){
if(null == redisUtil.get(userId)){
if(null !=redisUtil.get(userId+"incr")){
redisUtil.deleteKey(userId+"incr");
}
return true;
}
return false;
}
@GetMapping("/loginCode/{userId}")
public boolean loginCode(@PathVariable("userId") String userId, HttpServletRequest sesId){
return redisUtil.set(userId,sesId.getRemoteAddr(),60*60*2);
}
@GetMapping("/loginTry/{userId}")
public boolean loginTry(@PathVariable("userId") String userId){
return redisUtil.incr(userId+"incr");
}
@GetMapping("/safeCheck/{userId}")
public boolean safeCheck(HttpServletRequest addr ,@PathVariable("userId") String userId){
String raddr =(String) redisUtil.get(userId);
if(null== raddr){
return false;
}
if(raddr.equals(addr.getRemoteAddr())){
return true;
}
return false;
}
@GetMapping("/sendCode")
public boolean code(String emailTo){
return send.sendSimpleEmail(emailTo);
}
@GetMapping("/get/{userEmail}")
public String getCode(@PathVariable("userEmail") String userEmail){
return (String) redisUtil.get(userEmail);
}
}