一,简单操作Hash类型
Redis储存对象时可以选择使用Hash类型
使用Hash类型与之前操作JSON类似,只是调用的方法不一样
stringRedisTemplate.opsForHash()
之后就可以使用操作Hash类型的方法了
储存时,用putAll(key,Map)可以将一个map集合存到一个对象中
而使用put(key,fieldKey,fieldValue)则只能将一个键值对存到对象中
附上使用的代码:
@Override
public Result login(LoginFormDTO loginForm, HttpSession session) {
String code = stringRedisTemplate.opsForValue().get("user:code:" + loginForm.getPhone());
if(loginForm.getCode()==null && loginForm.getPassword()==null) return Result.fail("请填入完整信息!");
if(code==null) return Result.fail("请重新发送验证码!");
if(loginForm.getCode().equals(code) && !RegexUtils.isPhoneInvalid(loginForm.getPhone())){
User user = new User();
user.setPhone(loginForm.getPhone());
List<User> users = userMapper.selectUserList(user);
UserDTO u = new UserDTO();
if(users.size()==1){
String token = UUID.randomUUID(true).toString();
BeanUtils.copyProperties(users.get(0),u);
// session.setAttribute("user:user:"+loginForm.getPhone(), token);
Map<String, Object> userMap = BeanUtil.beanToMap(u,new HashMap<>(),
CopyOptions.create().setIgnoreNullValue(true).setFieldValueEditor((key,value) -> value.toString()));
stringRedisTemplate.opsForHash().putAll("user:user:"+token,userMap);
stringRedisTemplate.expire("user:user:"+token,30,TimeUnit.MINUTES);
return Result.ok(token);
}else{
return Result.fail("用户未注册!");
}
}
return Result.fail("手机号或验证码错误!");
}
二,拦截器
我记得之前虽然学习过拦截器,但是貌似没有动手写过。
1、首先定义一个拦截器类,它需要实现HandlerInterceptor接口
2、然后实现它的三个方法(preHandle(controller处理之前),afterCompletion(DispatcherServlet进行视图的渲染之后),postHandle(Controller方法处理完之后))
3、然后需要一个Mvc的配置类,需要实现WebMvcConfigurer接口,实现addInterceptors()方法,然后添加拦截器即可。
4、拦截器传参
由于拦截器并没有使用Bean注解,所以不能自动装配,
但是可以通过构造器传参
5、拦截器执行顺序
使用order(),数字越小越先执行,默认情况下都是0,这时谁在前面谁先执行
附上代码
拦截器1
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(UserHolder.getUser() == null){
response.setStatus(401);
return false;
}
return true;
}
}
拦截器2
public class RefreshTokenInterceptor implements HandlerInterceptor {
private StringRedisTemplate stringRedisTemplate;
public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// HttpSession session = request.getSession();
// Object user = session.getAttribute("user");
String token = request.getHeader("authorization");
if(token==null){
return true;
}
Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries("user:user:" + token);
if(userMap.isEmpty()){
return true;
}
UserDTO user = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);
UserHolder.saveUser(user);
stringRedisTemplate.expire("user:user:" + token,30, TimeUnit.MINUTES);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
UserHolder.removeUser();
}
}
mvc配置类
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).addPathPatterns("/**").order(0);
registry.addInterceptor(new LoginInterceptor()).excludePathPatterns(
"/shop/**",
"/voucher/**",
"/shop-type/**",
"/upload/**",
"/blog/hot",
"/user/code",
"/user/login"
).order(1);
}
}