2015-06-19 18 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

相關問題