2011-12-09 24 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