需求:根据是否登录来调整要显示给用户的内容
这里我们要使用spring的拦截器(它可以拦截来自浏览器的请求,然后在请求的开始和后面插入一些代码,解决多个请求共有的业务(耦合度低))
1封装一个获取cookie值的工具类 ,方便以后复用
public class CookieUtil {
public static String getValue(HttpServletRequest request, String name) {
if (request == null || name == null) {
throw new IllegalArgumentException("参数为空!");
}
//得到了所有的cookie对象,这是一个数组
Cookie[] cookies = request.getCookies();
//找到key为name的那个cookie
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals(name)) {
return cookie.getValue();
}
}
}
return null;
}
}
2编写工具类,暂存数据(容器作用),且避免多线程下的并发问题
@Component //考虑到多线程环境下的并发问题,我们把每个线程隔离一份 ThreadLocal可以解决
public class HostHolder {
//看源码后我们发现它是以线程为Key来存储值
private ThreadLocal<User> users = new ThreadLocal<>();
//存
public void setUser(User user) {
users.set(user);
}
//取
public User getUser() {
return users.get();
}
//清理
public void clear() {
users.remove();
}
}
3 service层处理查询逻辑(通过ticket查询用户)
public LoginTicket findLoginTicket(String ticket) {
return loginTicketMapper.selectByTicket(ticket);
}
4 编写拦截器
@Component
public class LoginTicketInterceptor implements HandlerInterceptor {
@Autowired
private UserService userService;
@Autowired
private HostHolder hostHolder;
@Override//在请求一开始就获得凭证 controller之前
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 从cookie中获取凭证
String ticket = CookieUtil.getValue(request, "ticket");
if (ticket != null) {
// 查询凭证
LoginTicket loginTicket = userService.findLoginTicket(ticket);
// 检查凭证是否有效
if (loginTicket != null && loginTicket.getStatus() == 0 && loginTicket.getExpired().after(new Date())) {
// 根据凭证查询用户
User user = userService.findUserById(loginTicket.getUserId());
// 在本次请求中持有用户
hostHolder.setUser(user);
}
}
return true;
}
@Override //controller之后
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { //获取容器里面的值 ,传给前端页面
User user = hostHolder.getUser();
if (user != null && modelAndView != null) {
modelAndView.addObject("loginUser", user);
}
}
@Override//模板引擎执行之后
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//清理容器
hostHolder.clear();
}
}
5配置拦截器
@Autowired
private LoginTicketInterceptor loginTicketInterceptor;
//除静态也页面外所有页面都要被拦截器拦截
registry.addInterceptor(loginTicketInterceptor)
.excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg");
6 处理前端页面(根据loginUser)