在上下文中从客户端向 ejb bean 注入参数

Inject a parameter from client to ejb bean in the context

Ejb客户端如何注入参数? 类似的东西:

final Hashtable<String, String> jndiProperties = new Hashtable<String, String>();
jndiProperties.put("java.naming.factory.initial", "org.ow2.carol.jndi.spi.MultiOrbInitialContextFactory");
jndiProperties.put("java.naming.factory.url.pkgs", "org.ow2.jonas.naming");
jndiProperties.put("java.naming.provider.url", "rmi://localhost:1099");

final Context context = new InitialContext(jndiProperties);
Object obj = context.lookup("MyEjbTest");

context.addToEnvironment("user", new Object());

在服务端,使用拦截器获取客户端注入的参数:

public Object intercept(InvocationContext ctx) throws Exception {

    Object o = ctx.getContextData().get("user");
    if (o != null) {
        LOG.info("Exists " + o.toString());
        return ctx.proceed();
    } else {
        return null;
    }
}

参数 user 永远不会注入到上下文中,并且在服务器端 o 始终为 null。有什么办法可以解决吗?

不,没有标准方法可以将数据从客户端隐式传递到 EJB。您必须通过方法参数显式地将数据传递给 EJB。

如果您使用的是 RMI-IIOP,那么您可以编写自己的 interceptor to transfer context data to the server and then store it in a thread local. If you're using WebSphere Application Server, you could use application context work areas (this was attempted to be standardized by JSR 149,但它被认为不够便携)。这些选项可能过于小众或过于繁琐,因此您最好直接通过方法参数显式传递数据。

使用 RMI-IIOP 发送附加上下文数据的完整示例非常广泛,但一般步骤是:

  1. 首先注册一个 ORBInitializer。请参阅其中的 javadoc,但由于 ORB 配置通常由应用程序服务器严格控制,因此您应该阅读您的应用程序服务器文档,特别是了解如何(或者如果它完全受支持)您可以添加 ORB 拦截器以及如何 class 正在加载。
  2. 在客户端中,您的 ORBInitializer 应该调用 ORBInitInfo.add_client_request_interceptor. In your implementation of the send_request method, call ClientRequestInfo.add_request_service_context
    1. 通常,您会为服务上下文 ID 保留带有 OMG 的供应商前缀,但如果它是您环境的本地(即,您不向第三方提供您的应用程序),那么您可能可以选择一个不会与您环境中的任何其他产品发生冲突。
    2. 您发送的字节由您选择。您的客户端可能会在本地线程中设置一些数据,然后您对 send_request 方法的实现会将数据序列化为 byte[] 以添加到 ServiceContext.
  3. 在服务器中,您的 ORBInitializer 应该调用 add_server_request_interceptor。您对该拦截器的实现将解码客户端发送的服务上下文,并可能在请求期间设置线程局部变量并在结束时将其删除。