您的位置:首页 > 其它

JBoss AS 7.1.1下,从远程客户端使用JNDI调用EJB

2014-03-09 15:15 381 查看
刚开始学习EJB,网上很多视频教程都是使用JBoss7之前的版本的应用服务器。在此,记录一下完成这个EJB HelloWorld 程序的过程。第一步:使用Eclipse或MyEclips创建一个EJB Project,在项目中编写EJBs,这个项目将被我们部署到JBoss AS 7.1.1服务器端。此处工程名为ejb_01
package com.chan.ejb;

public interface FirstEjb {
public String sayHello(String name);
}
定义好了EJB接口,再编写其实现类:
package com.chan.ejb;

import javax.ejb.Remote;
import javax.ejb.Stateless;

@Stateless
@Remote
public class FirstEjbBean implements FirstEjb {

@Override
public String sayHello(String name) {

return "你好," + name;

}

}
在编写这个企业Bean的时候,类名一般遵循Bean结尾的命名方式,并且要为该Bean配置注解。配置注解的时候要注意@Stateless和@Stateful只能2选1,但可以同时为其配置@Remote和@Local便可同时支持本地客户端和远程客户端的访问方式。编写好这个Bean之后,启动JBoss 7.1.1 ,然后就可以将该项目部署到服务器上了。这样,我们的EJB就写好了。接下来,我们开始编写远程客户端的代码,新建一个Java Project,名为ejb_01_client。这里我们将用到我们刚才定义的接口FirstEjb,将其以jar包的形式打包导入到现在的客户端工程ejb_01_client中,并将其加到类加载路径下。对了,别忘了将E:\jboss-as-7.1.1.Final\bin\client\jboss-client.jar加到客户端工程类路径下。好了,新建FirstEjbClient.java,代码如下:
package com.chan.ejb;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.chan.ejb.FirstEjb;

/** 通过jndi远程调用ejb
jboss7之前的做法
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
*/
public class FirstEjbClient {

public static void main(String[] args) throws Exception {
/*
这是JBoss7之前,远程客户端调用EJB的方式
InitialContext context = new InitialContext(); // 类似于一个工厂,在类路径下创建jndi.properties
FirstEjb firstEjb = (FirstEjb) context.lookup("FirstEjbBean/remote");
String s = firstEjb.saySomething("张三");
System.out.println(s);
*/

FirstEjb firstEjb = lookupRemoteStatelessEjbBean();
System.out.println(firstEjb);
String s = firstEjb.saySomething("张三");
System.out.println(s);

}

/**
* Looks up and returns the proxy to remote stateless calculator bean
*
* @return
* @throws NamingException
*/
private static FirstEjb lookupRemoteStatelessEjbBean() throws NamingException {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
final Context context = new InitialContext(jndiProperties);

final String appName = "";

final String moduleName = "ejb_01";

final String distinctName = "";

final String beanName = "FirstEjbBean";

final String viewClassName = FirstEjb.class.getName();

final String namespace = "ejb:" + appName + "/" + moduleName
+ "/" + distinctName + "/" + beanName + "!" + viewClassName;

System.out.println(namespace);

return (FirstEjb) context.lookup(namespace);

/*
return (RemoteCounter) context.lookup("ejb:" + appName + "/" + moduleName
+ "/" + distinctName + "/" + beanName + "!" + viewClassName + "?stateful");
*/
}

}
在这里解释解释客户端代码:
在JBoss7之前,JNDI是通过jnp那些东西来和服务器端进行连接并放回EJB代理对象的,没接触过,具体工作原理我也不太清楚。在这里说说JBoss7下的客户端代码,首先还是像以前的方式一样,通过在类路径下提供一个jndi.properties文件或直接在代码中向InitialContext中传入所需的JNDI属性和值,这里我们通过后者实现:
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
final Context context = new InitialContext(jndiProperties);
有了InitialContext之后,我们便可以调用context.lookup()获得通过JNDI返回的EJB代理对象了,但这里和以前有所区别的是,我们不可以直接通过context.lookup("FirstEjbBean/remote")这种方式之前进行查找了,lookup()方法中的参数将需要[ejb:命名空间]这样一个JNDI 名字的字符串,具体语法如下:
ejb:<app-name>/<module-name>/<distinct-name>/<bean-name>!<fully-qualified-classname-of-the-remote-
interface
>
有状态Bean则应为
ejb:<app-name>/<module-name>/<distinct-name>/<bean-name>!<fully-qualified-classname-of-the-remote-
interface
>?stateful
[/code]大概说说名字空间的各部分的意思:app-name:如果部署到服务器的是一个.ear包,那么app-name就为出去后缀.ear之后的包名。如果部署的是.war包或普通的.jar包,那么app-name留空即可,我自己这个工程是以.jar包部署的,所以app-name为空。module-name:此处就是部署到服务器上.war包或.jar包的名字,注意,module-name不能为空。distinct-name:这是一个可选的用于指定在JBoss AS7上具体的部署配置的一个参数名,不需要使用的话,留空即可,此处我们留空。bean-name:这是我们要使用lookup查找获取的Bean,这个项目中为FirstEjbBean,即FirstEjb的实现Bean,无需全限定类名,bean-name不能为空。
fully-qualified-classname-of-the-remote-
interface:这是我们写的EJB中暴露出来的接口FirstEjb的全限定类名,不能为空。
构造好了这个查找EJB使用的JNDI参数名后,调用lookup()方法便可以获得EJB代理对象并调用EJB了。
完成了上面的工作之后,还需要重要的一步,就是配置EJB客户端上下文属性,即在客户端项目类加载路径下,提供一个名为
jboss-ejb-client.properties的配置文件,我的文件配置信息如下:[code]
endpoint.name=client-endpointremote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=falseremote.connections=defaultremote.connection.default.host=localhostremote.connection.default.port = 4447remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=falseremote.connection.default.username=saremote.connection.default.password=sa配置客户端上下文属性(set up ejb cilent context properties):(此处大概翻译文档中的解释)ejb 客户端上下文是一个包含执行远程调用EJB的上下文信息的上下文。该客户端上下文可以和多个EJB receiver关联(原来没有加入该配置文件之前,我的程序一直出现异常:大概是:no ejb receiver handle the [namespace....]),每个EJB receiver可以处理不同的EJB调用,每个这样的EJB receiver知道它可以操作哪些EJB,并且知道哪个目标服务器用户处理对bean的调用。注意,此处的端口要为4447,而不是8080,4447是JBoss本地地址中的端口。这样我们运行客户端代码,就可以调用EJB了。文件中各项属性的具体说明,可以参见:https://docs.jboss.org/author/display/AS71/EJB+invocations+from+a+remote+client+using+JNDI
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: