2011-12-09 21 views
1

我有一個Java EE 6中的大型Web項目,到目前爲止一切都很好。將EJB與常規的Java類一起使用。試圖實例化一個無狀態的EJB

現在我添加一個接收twitter信息並返回一個字符串的新類。到目前爲止,字符串已經從twitter的JSON文件中提取出來,並準備好保存在我的數據庫中。我的問題是我不知道如何從通常處理我所有數據庫調用的EJB傳遞信息。我正在使用JPA並擁有一個DAO類,管理員可以訪問所有數據庫。我已經有一個方法updateDatabase(String)。我希望能夠從具有要添加的字符串的類中調用updateDatabase(String),但我不知道是否可以像這樣實例化無狀態bean。通常情況下,你注入bean,然後調用他們的類名來訪問他們的方法。我也可以試着從EJB內部引用生成類的twitter字符串,但是我必須在那裏實例化它,並混淆main()方法調用來執行。我不確定如何做到這一點。現在我的Twitter消費類只是一個主要方法的POJO。出於某種原因,某些庫方法在面向IOUtils()API的主體之外不起作用,直接說「實例不應該在標準編程中構建」。

因此,在更高層次的底線上,我只是問POJO如何通常「混合」到Java EE項目中,其中大多數類都是EJB和servlet。

編輯:上面在重讀後讓我感到困惑,所以我會盡量簡化它。基本上我有一個主要方法的類。我想調用處理數據庫訪問的EJB類,並將其稱爲updateDatabase(String)方法,並傳入字符串。我應該怎麼做?

編輯:所以它看起來像一個JNDI查找和子序列引用是這樣做的首選方式,而不是直接實例化EJB?

編輯:這些類都在同一個web項目。在同一個包中。我可以注入一個或將POJO轉換爲EJB。然而,POJO確實有一個主要的方法,並且一些庫文件不喜歡被實例化,所以在main中運行它似乎是最好的選擇。

我的主要代碼:

public class Driver { 

    @EJB 
    static RSSbean rssbean; 

    public static void main(String[] args) throws Exception { 

     System.setProperty("http.proxyHost", "proxya..com"); 
     System.setProperty("http.proxyPort", "8080"); 
     /////////////auth code///////////////auth code///////////////// 
     String username = System.getProperty("proxy.authentication.username"); 
     String password = System.getProperty("proxy.authentication.password"); 
     if (username == null) { 
      Authenticator.setDefault(new ProxyAuthenticator("", "")); 
     } 
     ///////////////end auth code/////////////////////////////////end 

     URL twitterSource = new URL("http://search.twitter.com/search.json?q=google"); 
     ByteArrayOutputStream urlOutputStream = new ByteArrayOutputStream(); 

     IOUtils.copy(twitterSource.openStream(), urlOutputStream); 
     String urlContents = urlOutputStream.toString(); 
     JSONObject thisobject = new JSONObject(urlContents); 
     JSONArray names = thisobject.names(); 
     JSONArray asArray = thisobject.toJSONArray(names); 
     JSONArray resultsArray = thisobject.getJSONArray("results"); 
     JSONObject(urlContents.substring(urlContents.indexOf('s')));     
     JSONObject jsonObject = resultsArray.getJSONObject(0); 

     String twitterText = jsonObject.getString("text");   
     rssbean.updateDatabase("twitterText"); 
    } 
} 

我也得到一個java.lang.NullPointerException地方約rssbean.updateDatabase("twitterText");

+1

你不要創建一個EJB實例。永遠。這是Conainer處理的事情。另一方面,你可以做的是在一個方法上放一個PostConstruct註解並在那裏執行某些操作(而不是構造函數),但這與你的問題無關 –

+1

好吧,EJB爲空的原因可能是因爲驅動程序類不是容器管理類。這應該只在Driver類是應用程序入口點類時纔有效(這是您可以在靜態字段中注入EJB的唯一方法)。但是,你說這是一個Web應用程序。那麼你從哪裏調用Driver.main()?無論如何,如果你確實需要在靜態方法中使用該代碼(假設它不是入口點),那麼我會看到JNDI查找或者在工廠模式中重構代碼,以便沿着這些行注入實例或其他東西。 –

+0

我只是使用主要方法來測試操作。我不一定需要它爲Web應用程序。雖然我不確定使用什麼機制來觸發從URL獲取數據然後添加到數據庫的操作。我需要某種自動執行。 – Randnum

回答

1

使用POJO作爲一個無狀態EJB,有什麼不妥的做法。

來自wikipedia:EJB是封裝應用程序業務邏輯的服務器端模型。

您的POJO類使用Web服務,因此它爲您執行業務邏輯。

編輯>在閱讀您的評論時,您是否嘗試從Java EE容器之外訪問EJB?因爲如果沒有,那麼你可以將EJB注入到另一個EJB中(它們必須是無狀態的,它們都是)

+0

不,他們都在同一個項目中。實際上在同一個包中。這只是一個EJB,另一個是執行這個單獨的Twitter操作的標準POJO。我還沒有考慮過把它作爲一個EJB,而是從哪裏調用它。我不得不刪除主要的班級,是嗎? – Randnum

+0

我還是不明白,主要方法在哪裏。您可以以任何方式注入EJB。這真的取決於你的Twitter POJO的方法被調用的方式。您可以將@Inject daoClass放入Twitter bean並調用其方法 –

+0

對不起,有一個主CLASS。它調用Twitter類?如果是這樣,我會創建Twitter類EJB,並將其注入到主類中。然後將您的DAO注入Twitter或Main,取決於您的軟件架構。無論如何,你可能知道,我要去哪裏。 –

6

您應該使用InitialContext#lookup方法從應用程序服務器獲取EJB引用。
例如:

@Stateless(name="myEJB") 
public class MyEJB { 

    public void ejbMethod() { 
    // business logic 
    } 

} 

public class TestEJB { 

    public static void main() { 
    MyEJB ejbRef = (MyEJB) new InitialContext().lookup("java:comp/env/myEJB"); 
    ejbRef.ejbMethod(); 
    } 
} 

然而,注意,用於查找EJB名稱可以是供應商特定的。另外,EJB 3。1介紹了適用於每個應用服務器的portable JNDI names的思想。

+0

謝謝,JNDI查找是我還沒有使用過的一件事。帶有註釋的JEE6使事情變得更加容易。我所做的只是創建一個EJB的靜態實例並調用該實例的方法。這樣做感覺不對,但我不知道爲什麼。 – Randnum

+0

太棒了! –

1

如果您有一個希望訪問EJB的獨立程序,您有幾個選項。

一個是簡單地使用JNDI來查找EJB。 EJB必須有一個Remote接口,並且您需要爲您的容器配置JNDI部件,並且在獨立應用程序中包含任何特定的容器罐。

另一種技術是使用稱爲「應用程序客戶端」的Java EE工件。在這裏,你的類有一個容器提供者包裝器,但是它提供了一個運行時環境,非常類似於在容器中運行類,特別是你得到了像EJB注入這樣的東西。

您的應用程序仍然在單獨的JVM中運行,因此您仍然需要引用遠程EJB,但應用程序客戶端容器處理了一大堆讓您的應用程序連接到服務器的鍋爐板。這也是一個Java EE工件,它也依賴於容器來配置和啓動應用程序客戶端應用程序。

最後,POJO與EJB容器交互的方式與容器內部署的POJO相比,基本沒有什麼區別。接口仍然是獲得EJB注入的問題(比以前更容易在Java EE 6中完成)或通過JNDI查找引用。唯一明顯的區別是部署在容器中的POJO可以使用Local接口而不是Remote。

+0

他們實際上在同一個Web項目中我只是想知道是否應該讓它成爲另一個EJB,將它作爲常規POJO,實例化另一個EJB並從另一個類引用它。或者我可以如何讓他們參考彼此。 – Randnum

+0

如果您不需要事務功能或其他EJB生命週期/攔截器功能,那麼只需將其設置爲POJO並繼續即可。並不是說EJB是特別昂貴的,或者是其中的任何一個,但是當「新TweetPojo()」完成這項工作時,就隨之去做。 –

+0

是的,我只需要把它放到數據庫中,並做到這一點,我沒有通過一個包含數據庫訪問方法的EJB。其他類和servlet使用這個EJB,所以我不認爲我可以將它轉換成POJO。 – Randnum