Quarkus中的会话范围
我正在将一个应用程序从Thorntail迁移到Quarkus。它在bean中使用会话范围注释,该注释在所有RESTAPI请求期间向感兴趣的任何服务提供令牌信息。但在Quarkus文档中,它表示对话范围未实现。我可以使用类似的功能吗 以下是我想做的:Quarkus中的会话范围,quarkus,Quarkus,我正在将一个应用程序从Thorntail迁移到Quarkus。它在bean中使用会话范围注释,该注释在所有RESTAPI请求期间向感兴趣的任何服务提供令牌信息。但在Quarkus文档中,它表示对话范围未实现。我可以使用类似的功能吗 以下是我想做的: @Path @ApplicationScoped public class FruitsResource { @Inject FruitsService fruitsService; @POST public int po
@Path
@ApplicationScoped
public class FruitsResource {
@Inject FruitsService fruitsService;
@POST
public int post (Fruit fruit) {
return fruitsService.post(fruit);
}
}
@Provider
@ApplicationScoped
private class AuthorizationFilter implements ContainerRequestFilter {
@Inject AuthorizationHolder authorizationHolder;
@Override
public void filter (ContainerRequestContext request) {
String token = request.getHeaderString(HttpHeaders.AUTHORIZATION);
Authorization authorization = createAuthorizationFromToken(token);
authorizationHolder.setAuthorization(authorization);
}
}
@ConversationScoped
private class AuthorizationHolder {
private Authorization authorization;
@Produces
public Authorization getAuthorization () {
return authorization;
}
public void setAuthorization (Authorization authorization) {
this.authorization = authorization;
}
}
@ApplicationScoped
private class FruitsService {
@Inject Authorization authorization;
@Inject EntityManager entityManager;
@Transactional
public void post (Fruit fruit) {
// do some complex validation with the authorization object
...
// persist object
entityManager.persist(fruit);
entityManager.flush();
return fruit.getId();
}
}
每个请求中是否存在
授权
标题?我想它是(或者应该是),在这种情况下,只使用@RequestScoped
而不是@ConversationScoped
应该可以工作。无论如何,这可能是最好的办法
如果头仅出现在“第一个”请求中,并且同一会话中的后续请求可以重用令牌,那么您可以将@ConversationScoped
替换为@SessionScoped
。不过,我认为强制在所有请求中都显示标头会更好
最后,如果您真的想模拟对话,您可以这样做(未经测试,甚至未在IDE中编写,仅从我的头顶):
@SessionScoped
私有类授权持有人{
私有ConcurrentMap授权=新ConcurrentHashMap();
公共授权getAuthorization(ContainerRequestContext请求){
返回authorizations.get(getConversationId(request));
}
public void setAuthorization(ContainerRequestContext请求,授权){
this.authorizations.put(getConversationId(请求),authorization);
}
私有字符串getConversationId(ContainerRequestContext请求){
多值映射查询=request.getUriInfo().getQueryParameters();
返回query.getFirst(“cid”);
}
}
但是,正如我上面所说的,我真的认为您应该将bean
@requestscope
设置为限定的,并强制客户端在每个请求中发送授权
头。您能更详细地描述您的用例吗?因为从您编写的内容来看,似乎requestscope对您来说已经足够了。在任何情况下,SessionScoped都应该在Quarkus中可用,并且您可以在此基础上实现对话。这正是Thorntail中的代码。如何使用SessionScoped在Quarkus中实现同样的效果@ladicek每次请求都会发送授权。即使如此,用RequestScope替换ConversationScope也不起作用。我在这里创建了一个显示此行为的测试:只需在quarkus:dev中运行,在swagger ui中添加任何令牌,并为您建议的SessionScoped解决方案执行端点,每个端点调用都必须通知一个名为cid的查询参数@LadicekConversation作用域就是这样工作的,如果我没记错的话。事实上,仅仅用RequestScope替换ConversationScope是不起作用的,因为用Products注释的方法。当这个方法被注释为requestScope时,它就工作了。啊,好的,我没有想到这一点。我还是CDI新手:-)
@SessionScoped
private class AuthorizationHolder {
private ConcurrentMap<String, Authorization> authorizations = new ConcurrentHashMap<>();
public Authorization getAuthorization(ContainerRequestContext request) {
return authorizations.get(getConversationId(request));
}
public void setAuthorization(ContainerRequestContext request, Authorization authorization) {
this.authorizations.put(getConversationId(request), authorization);
}
private String getConversationId(ContainerRequestContext request) {
MultivaluedMap<String, String> query = request.getUriInfo().getQueryParameters();
return query.getFirst("cid");
}
}