会话范围在Quarkus中

时间:2020-03-01 21:19:11

标签: quarkus

我正在将应用程序从Thorntail迁移到Quarkus。它在bean中使用对话作用域注释,该bean在所有其余api请求期间向对它感兴趣的任何服务提供令牌信息。但是在Quarkus文档中,它说没有实现对话范围。我可以使用类似的功能吗?

这就是我想要做的:

@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();
    }
}

1 个答案:

答案 0 :(得分:0)

每个请求中是否存在Authorization标头?我想这是(或应该是),在这种情况下,仅使用@RequestScoped代替@ConversationScoped应该可以。无论如何,这可能是最好的选择。

如果标头仅出现在“第一个”请求中,并且同一会话中的后续请求可以重用令牌,则可以将@ConversationScoped替换为@SessionScoped。我认为强制将标头显示在所有请求中会更好。

最后,如果您真的想模拟对话,则可以执行以下操作(未经测试,甚至没有用IDE编写,只是从我的头上来):

@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");
    }
}

但是,如上所述,我真的认为您应该制作bean @RequestScoped,并强制客户端在每个请求中发送Authorization标头。