server:
port: 80
servlet:
context-path: /
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_miaosha3?serverTimezone=Asia/Shanghai
username: root
password: 123456
redis:
host: 192.168.30.113
port: 6379
password:
connect-timeout: 10s
lettuce:
pool:
max-active: 8
max-wait: 200s
max-idle: 8
min-idle: 0
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
auto-mapping-behavior: full
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:mybatis/mapper/*.xml
package com.java1234.miaosha.controller;
import com.java1234.miaosha.constant.Constant;
import com.java1234.miaosha.entity.R;
import com.java1234.miaosha.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
/**
* token操作控制器
*/
@RestController
@RequestMapping("/")
public class TokenController {
@Autowired
private RedisUtil redisUtil;
@GetMapping(value = "/refreshToken")
public R refreshToken(HttpServletRequest request){
String token = request.getHeader("token");
System.out.println("a有效期:"+redisUtil.getExpire(Constant.REDIS_TOKEN_PREFIX+token));
redisUtil.expire(Constant.REDIS_TOKEN_PREFIX,token,Constant.REDIS_TOKEN_EXPIRE);
System.out.println("b有效期:"+redisUtil.getExpire(Constant.REDIS_TOKEN_PREFIX+token));
return R.ok();
}
}
package com.java1234.miaosha.controller;
import com.java1234.miaosha.constant.Constant;
import com.java1234.miaosha.entity.R;
import com.java1234.miaosha.entity.User;
import com.java1234.miaosha.service.IUserService;
import com.java1234.miaosha.util.Md5Util;
import com.java1234.miaosha.util.RedisUtil;
import com.java1234.miaosha.util.StringUtil;
import com.java1234.miaosha.util.UUIDUtil;
import com.java1234.miaosha.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/")
public class LoginController {
@Autowired
private IUserService userService;
@Autowired
private RedisUtil redisUtil;
/**
* 用户登录
* @return
*/
@RequestMapping("/login")
public R login(@RequestBody UserVo userVo){
System.out.println("userVo: "+userVo.toString());
if(userVo==null){
return R.error();
}
if(StringUtil.isEmpty(userVo.getUsername())){
return R.error("用户名不能为空!");
}
if(StringUtil.isEmpty(userVo.getPassword())){
return R.error("密码不能为空!");
}
User resultUser = userService.findByUserName(userVo.getUsername());
if(resultUser==null){
return R.error("用户名不存在! ");
}
if(!resultUser.getPassword().trim().equals(Md5Util.backMd5(userVo.getPassword().trim()))){
return R.error("用户名或者密码错误!");
}
String token= UUIDUtil.genUuid(); //生成token
redisUtil.set(Constant.REDIS_TOKEN_PREFIX,token,resultUser,Constant.REDIS_TOKEN_EXPIRE);
return R.ok(token);
}
}
package com.java1234.miaosha.constant;
/**
* @author java1234_小锋
* @site www.java1234.com
* @company Java知识分享网
* @create 2020-11-28 14:18
*/
public class Constant {
/**
* redis token前缀
*/
public static final String REDIS_TOKEN_PREFIX="tk";
/**
* redis 秒杀库存前缀
*/
public static final String REDIS_STOCK_PREFIX="st";
/**
* redis 秒杀商品是否秒杀完标识前缀
*/
public static final String REDIS_GOODS_MIAOSHA_OVER_PREFIX="over";
/**
* redis token有效期30分钟
*/
public static final Integer REDIS_TOKEN_EXPIRE=30*60;
/**
* redis 秒杀商品集合
*/
public static final String REDIS_MIAOSHA_GOODS="miaosha_goods_list";
/**
* redis 秒杀商品集合有效期60分钟
*/
public static final Integer REDIS_MIAOSHA_GOODS_EXPIRE=60*60;
/**
* redis 验证码前缀
*/
public static final String REDIS_VERIFYCODE_PREFIX="vc";
/**
* redis 验证码有效期5分钟
*/
public static final Integer REDIS_VERIFYCODE_EXPIRE=5*60;
}
package com.java1234.miaosha.config;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.time.Duration;
/**
* Redis配置类
*
* @author Administrator
*
*/
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private Integer port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.lettuce.pool.max-idle}")
private Integer maxIdle;
@Value("${spring.redis.lettuce.pool.min-idle}")
private Integer minIdle;
@Value("${spring.redis.lettuce.pool.max-active}")
private Integer maxTotal;
@Value("${spring.redis.lettuce.pool.max-wait}")
private Duration maxWaitMillis;
@Bean
LettuceConnectionFactory lettuceConnectionFactory() {
// 连接池配置
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxIdle(maxIdle == null ? 8 : maxIdle);
poolConfig.setMinIdle(minIdle == null ? 1 : minIdle);
poolConfig.setMaxTotal(maxTotal == null ? 8 : maxTotal);
poolConfig.setMaxWaitMillis(maxWaitMillis == null ? 5000L : maxWaitMillis.toMillis());
LettucePoolingClientConfiguration lettucePoolingClientConfiguration = LettucePoolingClientConfiguration.builder()
.poolConfig(poolConfig)
.build();
// 单机redis
RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
redisConfig.setHostName(host);
redisConfig.setPort(port);
if (password != null && !"".equals(password)) {
redisConfig.setPassword(password);
}
// redisConfig.setPassword(password);
return new LettuceConnectionFactory(redisConfig, lettucePoolingClientConfiguration);
}
@Bean(name="redisTemplate")
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(lettuceConnectionFactory);
//序列化类
MyRedisSerializer myRedisSerializer = new MyRedisSerializer();
//key序列化方式
template.setKeySerializer(new StringRedisSerializer());
//value序列化
template.setValueSerializer(myRedisSerializer);
//value hashmap序列化
template.setHashValueSerializer(myRedisSerializer);
return template;
}
@Bean(name="redisTemplate2")
public RedisTemplate<String, Object> redisTemplate2(LettuceConnectionFactory lettuceConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(lettuceConnectionFactory);
//序列化类
MyRedisSerializer myRedisSerializer = new MyRedisSerializer();
//key序列化方式
template.setKeySerializer(new StringRedisSerializer());
//value序列化
template.setValueSerializer(new StringRedisSerializer());
return template;
}
static class MyRedisSerializer implements RedisSerializer<Object> {
@Override
public byte[] serialize(Object o) throws SerializationException {
return serializeObj(o);
}
@Override
public Object deserialize(byte[] bytes) throws SerializationException {
return deserializeObj(bytes);
}
/**
* 序列化
* @param object
* @return
*/
private static byte[] serializeObj(Object object) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
return bytes;
} catch (Exception e) {
throw new RuntimeException("序列化失败!", e);
}
}
/**
* 反序列化
* @param bytes
* @return
*/
private static Object deserializeObj(byte[] bytes) {
if (bytes == null){
return null;
}
ByteArrayInputStream bais = null;
try {
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
throw new RuntimeException("反序列化失败!", e);
}
}
}
}
<template>
<div>
<img src="~@/assets/logo.png" height="120px" width="300px" alt="分布式电商秒杀系统">
</div>
</template>
<script>
import axios from 'axios'
import {getServerUrl} from "@/config/sys";
export default {
name: 'Header',
methods:{
refreshToken(){
let url=getServerUrl("refreshToken");
let token=window.sessionStorage.getItem("token");
axios.defaults.headers.common['token']=token;
axios.get(url,{})
.then(response=>{
console.log(response.data);
if(response.data.code==0){
console.log('token刷新成功');
}
}).catch(error=>{
alert(error+"-请联系管理员");
})
}
},
mounted () {
// setInterval(this.refreshToken,1000*60*10); //10分钟刷新一次token
setInterval(this.refreshToken,5000);
}
}
</script>
<style scoped>
</style>