仿牛客网社区项目(八)显示登录信息
显示登录信息
- 拦截器示例
- 定义拦截器,实现HandlerInterceptor
- 配置拦截器,为它指定拦截、排除的路径
- 拦截器应用
- 在请求开始时查询登录用户
- 在本次请求中持有用户数据
- 在模板视图上显示用户数据
- 在请求结束时清理用户数据
一、拦截器示例#
1.以定义拦截器,实现HandlerInterceptor#
①页面拦截器处理的是请求,属于表现层的逻辑,因此在Controller包下新建一个包Interceptor,在该包下新建一个AlphaInterceptor类,该类需实现HandleInterceptor接口
@Component
public class AlphaInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(AlphaInterceptor.class);
//在Controller之前执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.debug("preHandle: "+handler.toString());
return true;
}
//在Controller之后执行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
logger.debug("postHandle: "+handler.toString());
}
//在TemplateEngine之后执行
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
logger.debug("afterCompletion: "+handler.toString());
}
}
2.配置拦截器,为它指定拦截、排除的路径#
②写一个配置类,在之前写配置类主要是想在配置类中声明一个第三方的Bean,将其装配到容器当中,拦截器的逻辑和别的不太一样,要求在配置类中实现一个接口而不是简单的装配一个Bean。通过以下代码的reqistry实现对拦截器的注入。
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private AlphaInterceptor alphaInterceptor;
@Autowired
private LoginTicketInterceptor loginTicketInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(alphaInterceptor)
.excludePathPatterns("/css/*","/js/*","/img/*")
.addPathPatterns("/register","/login");
}
}
运行项目进行测试,分别输入主页及登入网址,观察控制台上不同的输出。
二 、拦截器应用#
需要实现的功能:在请求开始时查询登录用户,在本次请求中持有用户数据,在模板视图上显示用户数据,在请求结束时清理用户数据。
登录后,显示用户的逻辑如下图所示
①在Interceptor包下新建一个拦截器(其实拦截器是Controller的一种,实现的是表现层逻辑)
②先在util包下建一个在工具类,封装从request中获取cookie的方法
public class CookieUtil {
public static String getValue(HttpServletRequest request, String name){
if(request == null || name == null){
throw new IllegalArgumentException("参数为空!");
}
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie:cookies){
if(cookie.getName().equals(name)){
return cookie.getValue();
}
}
}
return null;
}
}
③通过获取的cookie中的信息,查询LoginTicket,并从中获取用户信息,在这之前需要在服务层先编写通过cookie中的信息获取LoginTicket的方法
public LoginTicket findLoginTicket(String ticket){
return loginTicketMapper.selectByTicket(ticket);
}
④在存储用户信息时需要考虑多线程的情况,不然会在并发的时候产生冲突,必须考虑线程隔离。java中的ThreadLocal工具可以解决该问题。新建一个工具类HostHolder,该类的起到一个容器的作用
/**
* 持有用户信息,用于代替session对象
*/
@Component
public class HostHolder {
private ThreadLocal<User> users = new ThreadLocal<>();
public void setUsers(User user) {
users.set(user);
}
public User getUser(){
return users.get();
}
public void clear(){
users.remove();
}
}
根据上述逻辑,表现层的代码如下
在请求开始时查询登录用户
在本次请求中持有用户数据
在模板视图上显示用户数据
在请求结束时清理用户数据
@Component
public class LoginTicketInterceptor implements HandlerInterceptor {
@Autowired
private UserService userService;
@Autowired
private HostHolder hostHolder;
@Override
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.setUsers(user);
}
}
return true;
}
@Override
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();
}
}
⑤注册拦截器,并声明拦截路径路径
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private AlphaInterceptor alphaInterceptor;
@Autowired
private LoginTicketInterceptor loginTicketInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(alphaInterceptor)
.excludePathPatterns("/css/*","/js/*","/img/*")
.addPathPatterns("/register","/login");
registry.addInterceptor(loginTicketInterceptor)
.excludePathPatterns("/css/*","/js/*","/img/*");
}
}
配置相关的.html文件
分类:
仿牛客网社区项目
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署