简体   繁体   English

WebSocket端点和CDI注入:作用域RequestScoped没有活动上下文

[英]WebSocket endpoint and CDI injection: No active contexts for scope RequestScoped

I want to inject a @RequestScoped CDI bean in my Java EE 7 WebSocket endpoint. 我想在我的Java EE 7 WebSocket端点中注入@RequestScoped CDI bean。

However I am getting error WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped . 但是我收到错误WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped

What am I doing wrong and why it is not possible? 我在做什么错,为什么不可能呢?

@Named
@RequestScoped
public class Storage {

}

Which I @Inject in the endpoint like this: 我在端点中@Inject像这样:

@ServerEndpoint("/serverpush")
public class ContratoEndpoint {

    @Inject
    private Storage storage;

}

And I am getting the following stack trace: 我得到以下堆栈跟踪:

org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped
    at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:689)
    at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:90)
    at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:165)
    at org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63)
    at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:83)
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:125)

As @John mentioned, RequestContext is not active in WebSocket methods. 如@John所述, RequestContext在WebSocket方法中不处于活动状态。 Instead of using Deltaspike (which is a good option), you can also write your own Interceptor to activate/deactivate weld RequestContext . 除了使用Deltaspike(这是一个不错的选择),您还可以编写自己的拦截器来激活/停用焊接RequestContext

As you are using Wildfly, you can use weld as a provided dependency : 使用Wildfly时,可以将weld用作提供的依赖项:

<dependency>
    <groupId>org.jboss.weld</groupId>
    <artifactId>weld-core</artifactId>
    <version>2.2.12.Final</version>
    <scope>provided</scope>
</dependency>

Then you can define an InterceptorBinding @RequestContextOperation : 然后,您可以定义一个InterceptorBinding @RequestContextOperation

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.interceptor.InterceptorBinding;

@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface RequestContextOperation
{

}

And the corresponding RequestContextInterceptor where we activate/deactivate the RequestContext : 和相应的RequestContextInterceptor我们激活/停用RequestContext

import javax.inject.Inject;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;

import org.jboss.weld.context.RequestContext;
import org.jboss.weld.context.unbound.Unbound;

@Interceptor
@RequestContextOperation
public class RequestContextInterceptor {

    /** The RequestContext */
    @Inject
    @Unbound
    private RequestContext m_requestContext;

    /**
     * 
     * @param p_invocationContext
     * @return
     * @throws Exception
     */
    @AroundInvoke
    public Object activateRequestContext(final InvocationContext p_invocationContext) throws Exception {
        try {
            m_requestContext.activate();
            return p_invocationContext.proceed();
        } finally {
            m_requestContext.invalidate();
            m_requestContext.deactivate();
        }
    }
}

You can then use the @RequestContextOperation annotation on your class or on a specific method : 然后,您可以在类或特定方法上使用@RequestContextOperation批注:

@ServerEndpoint("/serverpush")
public class ContratoEndpoint {

    @Inject
    private Storage storage;

    @OnMessage
    @RequestContextOperation
    public String handleMessage(String message){

        // Here the @RequestScoped bean is valid thanks to the @RequestContextOperation InterceptorBinding
        storage.yourMethod();
        ....
    }

}

WebSockets do not initialize a request scope context for their method invocations. WebSocket不会为其方法调用初始化请求范围上下文。 You can use deltaspike context control to manually start a request context for the method invocation. 您可以使用deltaspike上下文控制来手动启动方法调用的请求上下文。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM