-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
未能获取有效的上下文 #675
Comments
添加了也不行 |
我也遇到了同样的问题,使用的是spring-boot-starter-webflux 和 sa-token-reactor-spring-boot3-starter 1.39.0 /**
* 在当前线程的 SaRequest 包装对象
*
* @return /
*/
public static SaRequest getRequest() {
return getBoxNotNull().getRequest();
}
/**
* 在当前线程的 SaResponse 包装对象
*
* @return /
*/
public static SaResponse getResponse() {
return getBoxNotNull().getResponse();
}
/**
* 在当前线程的 SaStorage 存储器包装对象
*
* @return /
*/
public static SaStorage getStorage() {
return getBoxNotNull().getStorage();
} 我发现http请求中进行StpUtil.login()时,会调用两次getRequest,调用一次getStorage,其中在getStorage()时,报错:未能获取有效的上下文 分析源码发现box的初始化发生在此处:
public static void setContext(ServerWebExchange exchange) {
SaRequest request = new SaRequestForReactor(exchange.getRequest());
SaResponse response = new SaResponseForReactor(exchange.getResponse());
SaStorage storage = new SaStorageForReactor(exchange);
SaTokenContextForThreadLocalStorage.setBox(request, response, storage);
}
/**
* 基于 ThreadLocal 的 [ Box 存储器 ]
*/
public static ThreadLocal<Box> boxThreadLocal = new InheritableThreadLocal<>();
/**
* 初始化当前线程的 [ Box 存储器 ]
* @param request {@link SaRequest}
* @param response {@link SaResponse}
* @param storage {@link SaStorage}
*/
public static void setBox(SaRequest request, SaResponse response, SaStorage storage) {
Box bok = new Box(request, response, storage);
boxThreadLocal.set(bok);
} 两次getRequest使用的是同一个box,而getStorage重新初始化了一个box,也就是重新调用了setContext方法(setContext时,box是初始化成功的了,但是在getBoxNotNull时,拿到的为null) 执行过程中其实SaSession已经创建好,并且在debug时也可以通过打印的token拿出来,但是在SaStorage storage = SaHolder.getStorage();时发生错误,我发获取storage 我不知道是否是因为getStorage前调用了setContext重新初始化box导致的 |
public Mono<Result> login(AccountDTO accountDTO) {
return Mono.just(accountDTO)
.flatMap(dto -> {
if (StrUtil.isNotBlank(dto.getMail())) {
return getByMail(dto.getMail());
} else if (StrUtil.isNotBlank(dto.getUsername())) {
return getByUsername(dto.getUsername());
} else {
return Mono.error(new ServiceException(CommonResultType.PARAMETER_ERROR));
}
})
.map(account -> {
StpUtil.login(account.getAccountId());
return Result.success(StpUtil.getSessionByLoginId(account.getAccountId()));
});
}
public Mono<Result> login(AccountDTO accountDTO) {
return Mono.fromCallable(() -> {
if (StrUtil.isBlank(accountDTO.getPassword()) || StrUtil.isBlank(accountDTO.getMail())) {
return Result.fail(CommonResultType.PARAMETER_ERROR);
}
Account loginAccount = getByMail(accountDTO.getMail()).block();
StpUtil.login(loginAccount.getAccountId());
//登陆成功,返回token
return Result.success(StpUtil.getTokenInfo());
})
.subscribeOn(Schedulers.boundedElastic()) // 切换到 boundedElastic 线程池
;
} 两种写法,在执行getRequest和getStorage时都是不同的线程,但是不太清除为什么强制阻塞后可以执行成功 |
同样问题 |
spring-boot-starter-webflux,sa-token-reactor-spring-boot3-starter +1 |
#506 |
使用版本:
1.38.0
涉及的功能模块:
gateway
测试步骤:
WebClient.Builder请求后切换了线程,导致SaTokenContextForThreadLocalStorage的InheritableThreadLocal拿不到数据,但是WebClient是webflux的最佳请求方案
有没有办法在不添加ExecutorService的情况下解决这个问题?
The text was updated successfully, but these errors were encountered: