栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

仿牛客社区开发(登录模块-显示登录信息)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

仿牛客社区开发(登录模块-显示登录信息)

仿牛客社区开发(登录模块-显示登录信息)
  • 概述
  • 拦截器示例
    • 定义拦截器
    • 配置拦截器
  • 拦截器的应用
    • 配置拦截器 - LoginTicketInterceptor
    • 配置拦截器 - WebMvcConfig
  • 补充

概述


拦截器在本项目中的应用:

  • 服务器通过客户端request请求头中的cookie获取ticket(preHandle)
  • 根据ticket从login_ticket表中获取LoginTicket凭证示例(preHandle)
  • 根据登录凭证中的user_id找到对应user(preHandle)
  • 将user数据渲染到模板(postHandle)
  • 返回模板,线程结束(afterCompletion)
拦截器示例 定义拦截器
@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());
        //可以在request和response中加逻辑
        return true;//返回false,不往下执行
    }

    //在Controller之后执行,相当于对Controller最后的补充,所以会给modelAndView
    @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());
    }
}

配置拦截器

注入拦截器,静态资源随意访问,静态资源的路径被排除,要拦截的路径是/register, /login。
*.css表示static目录下任意文件中的css文件.

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    //注入拦截器
    @Autowired
    private AlphaInterceptor alphaInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(alphaInterceptor)
                .excludePathPatterns("*.css", "*.js", "*.png", "*.jpg", "*.jpeg")
                .addPathPatterns("/register", "/login");
    }
}

拦截器的应用 配置拦截器 - LoginTicketInterceptor
@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 {

        // 从request获取name为ticket的cookie value
        String ticket = cookieUtil.getValue(request, "ticket");

        if (ticket != null) {
            // 查询凭证实例oginTicket
            LoginTicket loginTicket = userService.findLoginTicket(ticket);
            // 检查凭证是否存在、有效,过期时间晚于当前时间
            if (loginTicket != null && loginTicket.getStatus() == 0 && loginTicket.getExpired().after(new Date())) {
                // 根据凭证查询用户实例user loginTicket->userId->user
                User user = userService.findUserById(loginTicket.getUserId());
                hostHolder.setUsers(user);// 保存用户数据,考虑到多线程并发,线程隔离用ThreadLocal
            }
        }
        return true;//如果是false后面就不执行了
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        User user = hostHolder.getUsers();
        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();
    }
}

cookieUtil
自定义cookieUtil,获取对应cookie的value

public class cookieUtil {

    //静态方法,不用容器调用了
    public static String getValue(HttpServletRequest request, String name) {
        if (request == null || name == null) {
            throw new IllegalArgumentException("参数为空!");
        }

        cookie[] cookies = request.getcookies();//得到了cookies列表
        if (cookies != null) {
            for (cookie cookie : cookies) {
                if (cookie.getName().equals(name)) {//遍历,找对应name的value
                    return cookie.getValue();
                }
            }
        }
        return null;
    }
}

HostHolder
自定义HosthHoder.java,声明ThreadLocal变量保存user数据,保证线程隔离

@Component
public class HostHolder {

    private ThreadLocal users = new ThreadLocal<>();

    public void setUsers(User user) {
        users.set(user);
    }

    public User getUsers() {
        return users.get();
    }

    public void clear() {
        users.remove();
    }
}

配置拦截器 - WebMvcConfig
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

  
    @Autowired
    private LoginTicketInterceptor loginTicketInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginTicketInterceptor)
                .excludePathPatterns("*.css", "*.js", "*.png", "*.jpg", "*.jpeg");
    }
}

补充

ThreadLocal如何保证线程隔离?
每个线程有一个ThreadLocalMap,key是ThreadLocal引用,value是要保存的数据。访问threadlocal变量的线程,都会在自己工作内存本地,保存该变量的副本,也就意味着将一个共享唯一的资源复制成多份,由各个线程独占。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/301350.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号