我如何确定泽西岛请求范围内的IM?

发布于 2025-01-26 02:49:31 字数 1341 浏览 2 评论 0原文

我有一些代码将在泽西岛请求上下文和泽西岛请求上下文之外(在另一个线程中)运行。在两种情况下,我都想访问一个数据,这是可选的,但是我需要知道是否可以从中删除它。

在泽西岛请求上下文中,它来自标题参数。我正在使用org.glassfish.hk2.api.servicelecator访问javax.ws.rs.container.containerrequestcontext我可以从中读取标题。但是,这是可选的,因此可能存在也可能不存在。在泽西岛请求上下文之外,我目前正在使用 mdc 存储并读取该值,但是,这是可选的。 (要传递两者之间的值,我在暂时上下文。)所有这些东西都在起作用。

我想知道从何处汲取价值,请求上下文或MDC。

我知道,如果我尝试访问containerRequestContext在泽西岛的org.glassfish.jersey.jersey.process.internal.requestscope 和它是null我是不在请求范围中,应该使用MDC。但是,我得到了无法说明的警告。 IllegalStateException被抛出并将其记录为服务定位器中的警告(我不能沉默)。

一种选项是将非选项哨兵值存储在MDC中,因为这始终可用。当我使用暂时性存储可选值时,我可以设置一个哨兵。如果存在前哨,请使用MDC,如果不是,请使用请求上下文。

我认为我期望工作的一种更清洁的方式只是检查我是否在泽西岛的请求范围内。但是,我找不到使用requestscopeservicelocator的方法。有人知道该怎么做吗?

I have some code that will run both inside Jersey request context and outside of Jersey request context (in another thread). I have a piece of data I want to access in both cases that's optional, but I need to know if I can pull it from.

Within Jersey request context it comes from a header parameter. I'm using a org.glassfish.hk2.api.ServiceLocator to access the javax.ws.rs.container.ContainerRequestContext from which I can read the header. However, this is optional, so it may or may not be present. Outside of Jersey request context I'm currently using MDC to store and read the value, but again, it's optional. (To pass the value between the two, I'm using in temporal context.) All of this stuff is working.

I want to know where to pull the value from, request context or MDC.

I know that if I try to access ContainerRequestContext outside of Jersey's org.glassfish.jersey.process.internal.RequestScope and it's null I'm not in request scope and should use MDC. But, I get unsilenceable warnings. An IllegalStateException is thrown and logged as a warning inside the service locator (which I can't silence).

One option would be to store a non-optional sentinel value in MDC, since that's always available. When I use temporal to store the optional value, I can set a sentinel. If the sentinel is present, use MDC, if not, use request context.

I think a cleaner way that I'd expect to work is just to check if I'm inside jersey's request scope. However, I can't find a way to do this, either using RequestScope or ServiceLocator. Does anyone know how to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烂人 2025-02-02 02:49:31

您可以注册一个调用代码的applicationEventListener,例如,

public class MyAppEventListener implements ApplicationEventListener {
    @Override
    public RequestEventListener onRequest(final RequestEvent event) {
        return new MyRequestListener();
    }

    public static class MyRequestListener implements RequestEventListener {
        @Override
        public void onEvent(final RequestEvent event) {
            if (event.getType() == RESOURCE_METHOD_START) {
                MyOtherCode.youAreNowInRequestScope();
            }
        }
    }
}

您的服务的run()方法中

environment.jersey().register(MyAppEventListener.class)

在 需要对此进行调整以调用某些非静态或触发其他请求事件,但我希望它有用。

You could register an ApplicationEventListener that calls your code, e.g.,

public class MyAppEventListener implements ApplicationEventListener {
    @Override
    public RequestEventListener onRequest(final RequestEvent event) {
        return new MyRequestListener();
    }

    public static class MyRequestListener implements RequestEventListener {
        @Override
        public void onEvent(final RequestEvent event) {
            if (event.getType() == RESOURCE_METHOD_START) {
                MyOtherCode.youAreNowInRequestScope();
            }
        }
    }
}

Then in your service's run() method (I see you've tagged this for Dropwizard):

environment.jersey().register(MyAppEventListener.class)

Presumably you'll need to tweak this to call something non-static or maybe trigger off a different request event, but I hope it's helpful.

杀お生予夺 2025-02-02 02:49:31

我遇到了同样的问题,我发现最接近的事情是:

class MyFactory implements Suplier<SomeInterface> {

    @Override
    public SomeInterface get() {
        if (inRequestScope()) {
            return new ClassA();
        } else {
            return new ClassB();
        }
    }

    private boolean inRequestScope() {
        try {
            requestScope.current();
            return true;
        } catch (IllegalStateException e) {
            return false;
        }
    }
}

查看当前这应该没有副作用。这不是理想的,但是我能找到的最好的解决方案。

您还可以@Inject MyFactory具有2个不同的实现A和B的代理,并返回这些,或添加Caching等。

I have had the same problem, the closest thing I have found to do is:

class MyFactory implements Suplier<SomeInterface> {

    @Override
    public SomeInterface get() {
        if (inRequestScope()) {
            return new ClassA();
        } else {
            return new ClassB();
        }
    }

    private boolean inRequestScope() {
        try {
            requestScope.current();
            return true;
        } catch (IllegalStateException e) {
            return false;
        }
    }
}

Looking at the implementation of current this should have no side effects. It's not ideal, but the best solution I could find.

You can also @Inject MyFactory with proxies to 2 different implementations, A and B, and return those, or add caching, etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文