ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

仿牛客网社区项目(八)显示登录信息

2022-04-30 15:32:11  阅读:150  来源: 互联网

标签:拦截器 仿牛 登录 void request 用户 handler 客网 public


显示登录信息

  • 拦截器示例
    • 定义拦截器,实现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");
    }
}

运行项目进行测试,分别输入主页及登入网址,观察控制台上不同的输出。

二 、拦截器应用

需要实现的功能:在请求开始时查询登录用户,在本次请求中持有用户数据,在模板视图上显示用户数据,在请求结束时清理用户数据。
登录后,显示用户的逻辑如下图所示
image-20220426224723104

①在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文件

标签:拦截器,仿牛,登录,void,request,用户,handler,客网,public
来源: https://www.cnblogs.com/nevererror/p/16210310.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有