📝 Sa-Token 異常處:未能獲取對應StpLogic,type=user
🧨 異常信息
cn.dev33.satoken.exception.SaTokenException: 未能獲取對應StpLogic,type=user
拋出位置:
throw new SaTokenException("未能獲取對應StpLogic,type="+ loginType).setCode(SaErrorCode.CODE_10002);
📌 問題原因分析
編號 | 原因 | 說明 |
---|---|---|
1 | type=user 拼寫錯誤或未定義 | 使用字符串 "user" 作為類型標識時,若未正確注冊,或拼寫錯誤(如 user vs user1 ),會導致找不到對應的 StpLogic 實例。 |
2 | 自定義 StpLogic 未初始化 | 若通過 new StpLogic(TYPE) 定義了自定義邏輯,但未在 Spring 容器中初始化,或未主動調用相關方法,會導致 StpLogic 實例為 null 。 |
3 | 未注冊到 Sa-Token 全局管理器 | 即使創建了 StpLogic 實例,也必須通過 SaManager.putStpLogic() 注冊到 Sa-Token 的全局上下文中,否則無法通過 type=user 查找。 |
? 解決方案
方案 1:使用 @PostConstruct
初始化并注冊 StpLogic
步驟:
- 在配置類(如
SatokenConfigure.java
)中取消注釋以下代碼:@PostConstruct @Order(0) public void registerUserStpLogic() {// 初始化 stpLogic,確保后續能正確獲取StpUserUtil.getStpLogic();// 注冊到 Sa-Token 全局管理器cn.dev33.satoken.SaManager.putStpLogic(StpUserUtil.stpLogic); }
- 關鍵點:
@PostConstruct
確保方法在 Spring 容器初始化后執行。@Order(0)
保證該方法在其他初始化邏輯(如rewriteSaStrategy()
)之前運行。
方案 2:使用 @Component
自動初始化 StpUserUtil
步驟:
- 在
StpUserUtil.java
類上添加注解:@Component public class StpUserUtil {... }
- 作用:
- Spring 會自動加載該類,觸發靜態屬性的初始化(如
StpLogic stpLogic
)。 - 無需手動調用
getStpLogic()
或@PostConstruct
。
- Spring 會自動加載該類,觸發靜態屬性的初始化(如
方案 3:手動調用初始化方法
適用于:不想修改配置或注解的情況。
步驟:
- 在 Spring Boot 啟動類中手動調用:
@SpringBootApplication public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);// 手動觸發初始化StpUserUtil.getStpLogic();cn.dev33.satoken.SaManager.putStpLogic(StpUserUtil.stpLogic);} }
? 驗證方法
- 登錄測試:
- 調用
/userLogin
接口登錄,確保返回 Token。
- 調用
- 權限校驗測試:
- 調用
/checkUserLogin
接口,請求頭中攜帶 Token。 - 預期結果:返回
{"data": true, ...}
,表示驗證通過。
- 調用
- 日志檢查:
- 檢查控制臺是否仍有
SaTokenException
拋出。
- 檢查控制臺是否仍有
🔄 常見錯誤排查
檢查項 | 建議操作 |
---|---|
type=user 是否拼寫錯誤? | 使用常量替代字符串,如 public static final String TYPE = "user"; |
StpUserUtil.stpLogic 是否為 null ? | 在啟動日志中打印 StpUserUtil.stpLogic 的值,確認是否初始化成功。 |
是否注冊到 SaManager ? | 在 SatokenConfigure.java 中檢查 SaManager.putStpLogic(...) 是否執行。 |
Spring 是否加載了 StpUserUtil ? | 確保 @Component 被啟用,或手動調用初始化方法。 |
📚 代碼示例
StpUserUtil.java
@Component
public class StpUserUtil {public static final String TYPE = "user";public static StpLogic stpLogic = new StpLogic(TYPE) {@Overridepublic String splicingKeyTokenName() {return super.splicingKeyTokenName() + "-user"; // satoken-user}};public static StpLogic getStpLogic() {return stpLogic;}
}
SatokenConfigure.java
@Configuration
public class SatokenConfigure {@PostConstruct@Order(0)public void registerUserStpLogic() {StpUserUtil.getStpLogic(); // 觸發初始化SaManager.putStpLogic(StpUserUtil.stpLogic); // 注冊到 Sa-Token}
}
🧩 補充建議
- 配置文件檢查:
- 在
application.yml
中確認 Sa-Token 的配置是否正確,例如:sa-token:token-name: satokentimeout: 86400
- 在
- 組件掃描:
- 確保
StpUserUtil
所在包被 Spring Boot 的組件掃描覆蓋(@SpringBootApplication
包路徑)。
- 確保
- 多租戶場景:
- 如果使用多
StpLogic
(如user
、admin
),需為每個類型單獨注冊。
- 如果使用多
? 總結
原因 | 解決方案 |
---|---|
type=user 拼寫錯誤 | 使用常量替代字符串 |
StpLogic 未初始化 | 使用 @PostConstruct 或 @Component |
未注冊到 SaManager | 調用 SaManager.putStpLogic(...) |