在远程调用期间管理无状态 EJB 的 "session" 或调用上下文的技术是什么?
What are the techniques to manage "session" or invocation context for Stateless EJBs during Remote calls?
我正在编写一个使用 RMI 调用 EJB 的应用程序。 EJB 是无状态的;业务需求不需要与客户的对话状态。
EJB 方法调用的参数之一是 "User" 对象,用于确定与调用关联的用户是否有权执行该操作。我们没有使用容器管理的 auth-auth:User 对象只是远程客户端提供的 POJO。
我想在 "session" 或调用上下文中全局创建此用户对象 available/injectable。我知道无状态 EJB 在 EJB 意义上没有 "session"; "session" 的意思是 "the current invocation"。例如,假设我们只有一个具有两种方法的远程 EJB:
myStatelessEjb.add(Thing, User)
myStatelessEjb.update(Thing, User)
这些方法调用了更多方法:涉及其他 EJB、Bean Validator 等。我不想在任何地方传递 User 对象,我想使 User 对象全局 available/injectable 具有上下文当前远程 EJB 调用。
我当然可以绕过 User 对象或用 "Thing" 封装它,但我认为不 "pollute" 我的对象和 API 与 User 可能是一个更好的设计,因为它是一个跨领域问题。
注释(强调):
- 我正在使用 RMI。
- 没有 HTTP 会话,因为我使用的是 RMI。
- 我没有使用容器管理的 auth-auth。
- 我正在使用容器管理的事务。
是否有适合这个问题的标准技术?例如也许远程客户端应该调用一个有状态的 EJB 来保存用户,或者 ThreadLocal 是合适的,或者我可以连接到容器管理的事务,或者可能已经有一个我不知道的适用的 session/context。
最简单的方法是将用户存储在 @RequestScoped CDI bean 中并根据需要注入:
@RequestScoped
public class RequestUser {
private User user;
//getter and setter for user
}
@Remote
@Statless
public class MyRemoteInterface {
@Inject
private RequestUser requestUser;
...
public void foo(User user, Bar bar) {
request.setUser(user);
...
}
}
@Stateless
public class OtherEJB() {
@Inject
private RequestUser user;
public void doBar(Bar bar) {
User user = user.getUser();
...
}
}
虽然 @SessionScoped
is useful for HTTP sessions only, @RequestScoped
具有更广泛的适用性:
public @interface RequestScoped
Specifies that a bean is request scoped.
The request scope is active:
- during the service() method of any servlet in the web application, during the doFilter() method of any servlet filter and when the
container calls any ServletRequestListener or AsyncListener,
- during any Java EE web service invocation,
- during any remote method invocation of any EJB, during any asynchronous method invocation of any EJB, during any call to an EJB
timeout method and during message delivery to any EJB message-driven
bean, and
- during any message delivery to a MessageListener for a JMS topic or queue obtained from the Java EE component environment.
我正在编写一个使用 RMI 调用 EJB 的应用程序。 EJB 是无状态的;业务需求不需要与客户的对话状态。
EJB 方法调用的参数之一是 "User" 对象,用于确定与调用关联的用户是否有权执行该操作。我们没有使用容器管理的 auth-auth:User 对象只是远程客户端提供的 POJO。
我想在 "session" 或调用上下文中全局创建此用户对象 available/injectable。我知道无状态 EJB 在 EJB 意义上没有 "session"; "session" 的意思是 "the current invocation"。例如,假设我们只有一个具有两种方法的远程 EJB:
myStatelessEjb.add(Thing, User)
myStatelessEjb.update(Thing, User)
这些方法调用了更多方法:涉及其他 EJB、Bean Validator 等。我不想在任何地方传递 User 对象,我想使 User 对象全局 available/injectable 具有上下文当前远程 EJB 调用。
我当然可以绕过 User 对象或用 "Thing" 封装它,但我认为不 "pollute" 我的对象和 API 与 User 可能是一个更好的设计,因为它是一个跨领域问题。
注释(强调):
- 我正在使用 RMI。
- 没有 HTTP 会话,因为我使用的是 RMI。
- 我没有使用容器管理的 auth-auth。
- 我正在使用容器管理的事务。
是否有适合这个问题的标准技术?例如也许远程客户端应该调用一个有状态的 EJB 来保存用户,或者 ThreadLocal 是合适的,或者我可以连接到容器管理的事务,或者可能已经有一个我不知道的适用的 session/context。
最简单的方法是将用户存储在 @RequestScoped CDI bean 中并根据需要注入:
@RequestScoped
public class RequestUser {
private User user;
//getter and setter for user
}
@Remote
@Statless
public class MyRemoteInterface {
@Inject
private RequestUser requestUser;
...
public void foo(User user, Bar bar) {
request.setUser(user);
...
}
}
@Stateless
public class OtherEJB() {
@Inject
private RequestUser user;
public void doBar(Bar bar) {
User user = user.getUser();
...
}
}
虽然 @SessionScoped
is useful for HTTP sessions only, @RequestScoped
具有更广泛的适用性:
public @interface RequestScoped
Specifies that a bean is request scoped.
The request scope is active:
- during the service() method of any servlet in the web application, during the doFilter() method of any servlet filter and when the container calls any ServletRequestListener or AsyncListener,
- during any Java EE web service invocation,
- during any remote method invocation of any EJB, during any asynchronous method invocation of any EJB, during any call to an EJB timeout method and during message delivery to any EJB message-driven bean, and
- during any message delivery to a MessageListener for a JMS topic or queue obtained from the Java EE component environment.