2015-06-19 35 views
2

我正在编写一个使用RMI来调用EJB的应用程序。 EJB是无状态的;业务需求不需要与客户交谈。在远程调用期间为无状态EJB管理“会话”或调用上下文的技术有哪些?

EJB方法调用的参数之一是用于确定与调用相关联的用户是否有权执行该操作的“用户”对象。我们没有使用容器管理的auth-auth:User对象只是远程客户端提供的POJO。

我想在“会话”或调用上下文中将此用户对象设置为全局可用/可注入。我知道无状态EJB在EJB的意义上没有“会话”;我所说的“会话”是指“当前的调用”。例如,假设我们只用两种方法之一远程EJB:

  • myStatelessEjb.add(Thing, User)
  • myStatelessEjb.update(Thing, User)

这些方法调用更多的方法:有其他的EJB,豆校验等。相反比传递User对象无处不在,我想通过当前的远程EJB调用的上下文使User对象全局可用/可注入。

我当然可以传递User对象或用“Thing”封装它,但我想也许这是一个更好的设计,不会“污染”用户的对象和API,因为这是一个横切关注。

笔记(为了强调):

  • 我使用RMI。
  • 没有HTTP会话,因为我正在使用RMI。
  • 我没有使用容器管理的auth-auth。
  • 我正在使用容器管理的事务。

有没有适合这个问题的标准技术?例如也许远程客户端应该调用一个有状态的EJB来保存用户,或者ThreadLocal是合适的,或者我可以挂钩容器管理的事务,或者已经有一个我不知道的适用的会话/上下文。

+1

标准技术是使用容器管理auth认证... –

+0

远程客户端正在处理授权,它不是容器管理。标准技术不适用于我的情况,所以我正在寻找替代品。对不起,如果不明确,@SteveC。 – DavidS

+0

“业务需求不需要与客户交谈。”您刚刚*表示*要求与客户进行会话状态。您需要使有问题的EJB处于有状态。 – EJP

回答

2

最简单的方法将是对用户存储在@RequestScoped CDI豆和注入,作为必需的:

@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仅用于HTTP会话有用,@RequestScoped有更广泛的适用性:

public @interface RequestScoped

指定bean是请求作用域。

的请求范围是活性:在web应用任何servlet的service()方法时

  • ,任何Servlet过滤器的doFilter()方法时,并且当 容器调用任何ServletRequestListener或AsyncListener ,
  • 任何Java EE web服务调用期间
  • 任何EJB的任何异步方法调用期间的任何EJB中任远程方法调用,任何呼叫期间一个EJB timeou期间t方法以及在将消息传递给任何EJB消息驱动的消息驱动期间,以及在从Java EE组件环境获得的JMS主题或队列的MessageListener期间向任何EJB消息驱动的bean和
  • 发送消息。
+0

好悲伤,那很简单!请求范围在任何EJB的任何远程方法调用期间都是活动的([ref](http://docs.oracle.com/javaee/6/api/javax/enterprise/context/RequestScoped.html))。我刚才认为它就像会话作用域一样,只在HTTP会话期间才有效。我会在星期一进行测试,但这对我来说很合适。 – DavidS

相关问题