12

我是 Java EE 的新手。目前我正在阅读Sun Microsystems的 The Java EE 6 Tutorial, Volume 1 (Basic Concepts Beta)。为了摆脱单调的阅读时间,我玩了一些其他人编写的 Java EE 项目/代码。

我来自东南。我的脑海里仍然充满了 SE。在 SE(两层应用程序)中,我使用

DATABASE_URL = "jdbc:mysql://something.db_server.com/db_name"

这就是我的客户知道数据库服务器在哪里的方式。

在我看到的一个 Java EE 示例中

// Access JNDI Initial Context.

Properties p = new Properties();

p.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
p.put("java.naming.provider.url","jnp://localhost:1099");
p.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");

InitialContext ctx = new InitialContext(p);

// Change jndi name according to your server and ejb

HelloRemote remote = (HelloRemote) ctx.lookup("HelloBean/remote");

msg = "Message From EJB --> " + remote.sayHello();

这个我明白。该代码具有 url 和端口号。有这条线

p.put("java.naming.provider.url","jnp://localhost:1099");

客户端通过 url 知道服务器在哪里以及要敲哪个端口。我认为代码是在 Java EE 5 时编写的。

今天我发现了另一个使用 Netbeans 7、Java EE 6 和 GlassFish 3 的示例。客户端代码

@EJB
private static MySessionRemote mySession;

/**
 * @param args the command line arguments
 */

public static void main(String[] args) {
    JOptionPane.showMessageDialog(null, 
            "result = " + mySession.getResult());
}

这是链接 http://netbeans.org/kb/docs/javaee/entappclient.html

没有给出 url 和端口号。

Java EE 6 Development with Netbeans 7 by David R. Heffelfinger 在第 7 章中有一个类似的例子。作者没有在书中解释它是如何完成的。我认为他做到了,但我可能错过了……</p>

我的问题是客户端如何在没有 url 的情况下定位服务器?它是否在这些 xml 文件之一中说明?客户端可以在加利福尼亚,GlassFish Server 可以在纽约。任何人都可以向我解释或指向我可以找到答案的任何教程/博客/文章吗?

谢谢你。

4

2 回答 2

9

这里有两件事正在发生。

第一件事是在 Java EE 中没有指定获取对远程 EJB 的引用的方式。您受个别供应商认为应该如何做的摆布。

尽管 JNDI 是用于此的事实上的标准,但即使这本身也不是强制性的。

示例:JBoss 直到 AS7

在 JBoss AS 直到 AS 7 中,使用以下序列来获取远程引用:

Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
env.put(Context.PROVIDER_URL, "jnp://myserver.example.com:1099");
InitialContext context = new InitialContext(env);

Bean bean = (Bean) context.lookup("myear/MyBean/remote");

在这里,远程服务器的 URL 被提供给初始上下文,并从该上下文中检索一个 bean。(请注意,您不能在此处添加众所周知的“java:/”前缀,否则它将被 JNDI 拦截并在本地解析,尽管在远程上下文中进行了查找)

由于该方法如上所述未标准化,因此单个供应商可以在不同的实现版本之间完全更改它。即使对于相同 Java EE 版本的实现也是如此。

示例:JBoss AS7

在 JBoss AS 7 中,JBoss 想要远离 JNDI(因为没有指定必须使用 JNDI),现在它大约以以下方式发生:

您首先需要jboss-ejb-client.properties使用以下上下文将文件放在类路径中:

endpoint.name = client-endpoint
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED = false
remote.connections = default
remote.connection.default.host = myserver.example.com
remote.connection.default.port = 4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS = false

并使用如下代码:

Properties env = new Properties();
env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
InitialContext context = new InitialContext(env);

Bean bean = (Bean) context.lookup("ejb:/myear/mymodule/MyBean!com.example.Bean");

因此,从代码看来,似乎没有给出 URL,但它静态隐藏在配置文件中。


应用程序客户端容器

今天我发现了另一个使用 Netbeans 7、Java EE 6 和 GlassFish 3 的示例。客户端代码 [...]

这是另一回事。这里展示了一个所谓的应用程序客户端容器(又名 ACC)。

这与上面的示例不同,其中 Java SE 应用程序使用 JNDI 联系远程服务器。Application Client Container 在 Java EE 中有点晦涩难懂。这个想法似乎是您从服务器(如 Applet 或 Java Web Start 应用程序)动态下载客户端代码,然后它神奇地“知道”它的来源。主类中对(静态)注入的支持非常有限,您可以使用它直接注入远程 bean。

Application Client Container 是 Java EE 早期的一个想法,据我所知,它从未受到太多关注。经过这么多年,它在最初的构想之后从未有过太大的进步。由于它仍然需要完成大量特定于供应商的事情,我认为大多数人不会为此烦恼,而只是使用 JNDI。

于 2012-11-30T14:25:33.827 回答
2

需要有一个jndi.properties包含配置数据的文件。即使客户端需要连接到与客户端在同一主机上运行的服务器,客户端也无法神奇地知道要连接的服务器 - 仍然可以有多个。

不过这个例子很奇怪——EJB 注释表明它应该在 Java EE 容器中运行,而不是作为客户端应用程序运行。

我还想指出,在客户端应用程序中调用 EJB 并不常见。它更像是一种服务器端技术。如果您想为客户端应用程序提供一个接口,那么使用它更容易和更便携,例如通过 JAX-RS 使用 RESTful Web 服务。

于 2012-11-30T10:28:45.360 回答