<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      使用線程本地變量存儲會員信息

      線程本地變量

      功能:JWT單點登錄時,后端通過前端請求header中的token解析出會員信息,這樣就可以不通過前端傳遞就可以獲取當前會員的信息。

      線程本地變量
      import com.guaigen.train.common.resp.MemberLoginResp;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      
      public class LoginMemberContext {
          private static final Logger LOG = LoggerFactory.getLogger(LoginMemberContext.class);
      
          private static ThreadLocal<MemberLoginResp> member = new ThreadLocal<>();
      
          public static MemberLoginResp getMember() {
              return member.get();
          }
      
          public static void setMember(MemberLoginResp member) {
              LoginMemberContext.member.set(member);
          }
      
          public static Long getId() {
              try {
                  return member.get().getId();
              } catch (Exception e) {
                  LOG.info("獲取會員登錄信息異常:{}", e);
                  throw e;
              }
          }
      }
      

      定義了一個名為 LoginMemberContext 的工具類,該類使用了 ThreadLocal 來存儲和獲取當前會員的登錄信息(MemberLoginResp)。ThreadLocal 確保每個線程都有自己獨立的 MemberLoginResp 實例,這在多線程環境中非常有用,例如在 Web 應用程序中,每個請求由單獨的線程處理。

      代碼的主要功能如下:

      1. 獲取當前會員信息

        • getMember() 方法用于獲取當前線程中存儲的會員登錄信息。
      2. 設置當前會員信息

        • setMember(MemberLoginResp member) 方法用于將會員信息存儲到當前線程中。
      3. 獲取會員ID

        • getId() 方法用于獲取當前線程中存儲的會員ID。該方法包含了異常處理,如果在獲取會員ID時發生異常,將記錄錯誤信息并拋出異常。

      這種設計確保了每個線程的登錄上下文是獨立的,不會相互影響,適合在需要線程隔離的場景中使用。

      攔截器攔截線程本地變量

      攔截器
      import cn.hutool.core.util.StrUtil;
      import cn.hutool.json.JSONObject;
      import cn.hutool.json.JSONUtil;
      import com.guaigen.train.common.util.JwtUtil;
      import com.guaigen.train.common.context.LoginMemberContext;
      import com.guaigen.train.common.resp.MemberLoginResp;
      import jakarta.servlet.http.HttpServletRequest;
      import jakarta.servlet.http.HttpServletResponse;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.stereotype.Component;
      import org.springframework.web.servlet.HandlerInterceptor;
      
      /**
       * 攔截器:Spring框架特有的,常用于登錄校驗,權限校驗,請求日志打印
       */
      @Component
      public class MemberInterceptor implements HandlerInterceptor {
      
          private static final Logger LOG = LoggerFactory.getLogger(MemberInterceptor.class);
      
          @Override
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
              //獲取header的token參數
              String token = request.getHeader("token");
              if (StrUtil.isNotBlank(token)) {
                  LOG.info("獲取會員登錄token:{}", token);
                  JSONObject loginMember = JwtUtil.getJSONObject(token);
                  LOG.info("當前登錄會員:{}", loginMember);
                  MemberLoginResp member = JSONUtil.toBean(loginMember, MemberLoginResp.class);
                  LoginMemberContext.setMember(member);
              }
              return true;
          }
      }
      
      基于 Spring 框架的攔截器 (`Interceptor`),名為,用于在每次 HTTP 請求處理之前執行一些操作,主要功能是驗證用戶的登錄狀態,并將登錄信息保存到當前線程的上下文中。

      主要功能:

      1. 獲取 Token

        • 在每次請求處理之前,攔截器會從請求的 header 中獲取 token 參數。
        • StrUtil.isNotBlank(token) 用于檢查 token 是否非空且非空白字符。
      2. 解析 Token

        • 如果 token 存在且有效,攔截器使用 JwtUtil.getJSONObject(token) 方法將 token 解析為 JSONObject 對象。
        • 日志記錄:攔截器會將獲取到的 token 以及解析后的會員信息記錄到日志中,便于跟蹤和調試。
      3. 保存會員登錄信息

        • 解析后的 JSONObject 對象會被轉換為 MemberLoginResp 對象。
        • 調用 LoginMemberContext.setMember(member) 方法,將該會員信息存儲到當前線程的上下文中,以便在后續請求處理中使用。
      4. 繼續處理請求

        • 如果攔截器成功獲取并處理了 token,會返回 true,表示可以繼續處理該請求。否則,請求可能會被阻止或進一步處理。

        這個攔截器通常用于登錄驗證,確保請求中包含有效的 token,并將登錄信息加載到上下文中供后續使用。這樣的設計在需要用戶認證和權限管理的場景中非常常見。

      可能的擴展:

      • 權限校驗:除了登錄驗證,還可以擴展該攔截器,添加權限校驗功能,確保用戶有權訪問某些資源或執行特定操作。
      • 日志記錄:記錄更多的請求細節,如請求路徑、請求參數等,以便進行審計和問題排查。

      配置文件

      config
      import com.guaigen.train.common.interceptor.MemberInterceptor;
      import jakarta.annotation.Resource;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
      import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
      
      @Configuration
      public class SpringMvcConfig implements WebMvcConfigurer {
          @Resource
          MemberInterceptor memberInterceptor;
      
          public void addInterceptors(InterceptorRegistry registry) {
              registry.addInterceptor(memberInterceptor)
                      .addPathPatterns("/**")
                      .excludePathPatterns(
                              "/member/hello",
                              "/member/member/sendCode",
                              "/member/member/login"
                      );
          }
      }
      
      Spring MVC 配置類,用于注冊并配置攔截器 `MemberInterceptor`。

      代碼解析:

      1. @Configuration 注解

        • 這個類被標注為一個配置類,意味著它定義了一些 Spring 容器的配置信息。
      2. WebMvcConfigurer 接口

        • SpringMvcConfig 實現了 WebMvcConfigurer 接口,這是 Spring MVC 提供的一個擴展點,允許你自定義配置 MVC 的行為,而不需要繼承 WebMvcConfigurerAdapter(在 Spring 5 中已廢棄)。
      3. @Resource 注解

        • @Resource 注解用于自動注入 MemberInterceptor 實例。Spring 將自動掃描并注入已定義的 MemberInterceptor Bean。
      4. addInterceptors 方法

        • addInterceptors(InterceptorRegistry registry) 方法用于注冊攔截器,并配置它應用于哪些請求路徑。
      5. 配置攔截器路徑

        • registry.addInterceptor(memberInterceptor)MemberInterceptor 添加到攔截器鏈中。
        • .addPathPatterns("/**") 指定攔截器應用于所有路徑(/** 表示匹配所有路徑)。
        • .excludePathPatterns("/member/hello", "/member/member/sendCode", "/member/member/login") 指定某些路徑不被攔截器攔截,這通常是登錄、驗證碼發送等公共接口。

      功能概述:

      • 全局攔截

        • 這個配置類將 MemberInterceptor 應用于所有請求路徑,但排除了一些指定的公共路徑。這意味著除了登錄和發送驗證碼的路徑外,所有其他路徑都將經過 MemberInterceptor 的處理。
      • 典型場景

        • 這種配置方式通常用于保護應用的業務邏輯部分,確保只有通過認證的用戶才能訪問特定資源。同時,也保留了一些不需要認證的公共接口供外部使用。

      可擴展性:

      • 根據需要,增加或減少 excludePathPatterns 中的路徑,以控制哪些請求路徑不需要經過攔截器。
      • 如果有多個攔截器,也可以通過 registry.addInterceptor(...) 繼續添加和配置其他攔截器。

      后端使用

      后端Service調用
      import cn.hutool.core.bean.BeanUtil;
      import cn.hutool.core.date.DateTime;
      import com.guaigen.train.common.context.LoginMemberContext;
      import com.guaigen.train.common.util.SnowUtil;
      import com.guaigen.train.member.domain.Passenger;
      import com.guaigen.train.member.mapper.PassengerMapper;
      import com.guaigen.train.member.req.PassengerSaveReq;
      import jakarta.annotation.Resource;
      import org.springframework.stereotype.Service;
      
      @Service
      public class PassengerService {
      
          @Resource
          private PassengerMapper passengerMapper;
      
          public void save(PassengerSaveReq req) {
              DateTime now = DateTime.now();
              Passenger passenger = BeanUtil.copyProperties(req, Passenger.class);
              passenger.setMemberId(LoginMemberContext.getId());
              passenger.setId(SnowUtil.getSnowflakeNestId());
              passenger.setCreatedTime(now);
              passenger.setModifiedTime(now);
              passengerMapper.insert(passenger);
          }
      }
      

      其中passenger.setMemberId(LoginMemberContext.getId());就是通過線程本地變量獲取memberId會員信息

      posted @ 2024-09-03 17:52  魚擺擺不擺  閱讀(55)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲综合网国产精品一区| 国产丰满麻豆videossexhd| 日韩午夜福利片段在线观看| 性欧美vr高清极品| 亚洲日韩久久综合中文字幕| av综合亚洲一区二区| 国产一区二区日韩在线| 亚洲一区成人在线视频| 国产精品 无码专区| 顶级少妇做爰视频在线观看| 四虎影视一区二区精品| 十八禁在线观看视频播放免费| 在线亚洲妇色中文色综合| 国产精品中文字幕久久| 97在线精品视频免费| 国产精品一区二区国产馆| 久久青草国产精品一区| 插入中文字幕在线一区二区三区| 亚洲国产长腿丝袜av天堂| 亚洲码亚洲码天堂码三区| 一面膜上边一面膜下边视频| 无码熟妇人妻AV影音先锋| 国产一卡2卡三卡4卡免费网站| 久久精品国产亚洲αv忘忧草| 天堂网在线观看| 精品无码一区在线观看| av午夜福利一片免费看久久| 革吉县| 黄色三级亚洲男人的天堂| 国产精品 无码专区| 国产日产免费高清欧美一区| 九九热精品视频在线免费| 五月花成人网| 国产欧美亚洲精品a| 久久精品娱乐亚洲领先| 男女裸体影院高潮| 国産精品久久久久久久| 激情97综合亚洲色婷婷五| 国产免费高清69式视频在线观看 | 一区二区三区四区激情视频| 欧美猛少妇色xxxxx|