1. JBoss安装与启动
按照http://www.blogjava.net/lingyu/articles/78572.html 文章步骤按照和启动EJB。 注意如果EJB无法启动,多半是没有安装好,或者JBOSS_HOME环境变量或者JAVA_HOME环境变量没有设置好的原因。
2. EJB服务端
- package org.martin.common.communication.ejb;
- //EJB的方法参数、返回值Bean
- public class EjbMessage implements Serializable
- {
- private static final long serialVersionUID = 1L;
- public long commandID=0;
- public Object obj;
- }
- public interface Hello extends EJBObject {
- public EjbMessage getHello(EjbMessage para) throws java.rmi.RemoteException;
- }
- public interface HelloHome extends EJBHome {
- Hello create() throws java.rmi.RemoteException, CreateException;
- }
- package org.martin.server.communication.ejb
- public class HelloEJB implements SessionBean{
- private static final long serialVersionUID = 1L;
- public void setSessionContext(SessionContext arg0) throws EJBException,
- RemoteException{
- }
- public void ejbRemove() throws EJBException, RemoteException{
- System.out.println("EJB ejbRemove");
- }
- public void ejbActivate() throws EJBException, RemoteException{
- System.out.println("EJB ejbActivate");
- }
- public void ejbPassivate() throws EJBException, RemoteException{
- System.out.println("EJB ejbPassivate");
- }
- public void ejbCreate(){
- System.out.println("EJB ejbCreate");
- }
- public EjbMessage getHello(EjbMessage para){
- EjbMessage reObj = new EjbMessage();
- reObj.commandID = para.commandID;
- reObj.obj = para.obj + " is echo by server";
- return reObj;
- }
- }
package org.martin.common.communication.ejb;
//EJB的方法参数、返回值Bean
public class EjbMessage implements Serializable
{
private static final long serialVersionUID = 1L;
public long commandID=0;
public Object obj;
}
public interface Hello extends EJBObject {
public EjbMessage getHello(EjbMessage para) throws java.rmi.RemoteException;
}
public interface HelloHome extends EJBHome {
Hello create() throws java.rmi.RemoteException, CreateException;
}
package org.martin.server.communication.ejb
public class HelloEJB implements SessionBean{
private static final long serialVersionUID = 1L;
public void setSessionContext(SessionContext arg0) throws EJBException,
RemoteException{
}
public void ejbRemove() throws EJBException, RemoteException{
System.out.println("EJB ejbRemove");
}
public void ejbActivate() throws EJBException, RemoteException{
System.out.println("EJB ejbActivate");
}
public void ejbPassivate() throws EJBException, RemoteException{
System.out.println("EJB ejbPassivate");
}
public void ejbCreate(){
System.out.println("EJB ejbCreate");
}
public EjbMessage getHello(EjbMessage para){
EjbMessage reObj = new EjbMessage();
reObj.commandID = para.commandID;
reObj.obj = para.obj + " is echo by server";
return reObj;
}
}
3. 部署EJB
(1)将服务端和common的代码用eclipse导出jar包,命名为Hello.jar。
(2)将EJB描述文件ejb-jar.xml放入导出的Hello.jar包中的META-INF目录下(与META-INF置于同一目录),ejb-jar.xml文件内容如下所示:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
- <ejb-jar>
- <description>
- This is Hello EJB example
- </description>
- <display-name>HelloBean</display-name>
- <enterprise-beans>
- <session>
- <display-name>Hello</display-name>
- <ejb-name>Hello</ejb-name>
- <home>org.martin.common.communication.ejb.HelloHome</home>
- <remote>org.martin.common.communication.ejb.Hello</remote>
- <ejb-class>org.martin.server.communication.ejb.HelloEJB</ejb-class>
- <session-type>Stateless</session-type>
- <transaction-type>Container</transaction-type>
- </session>
- </enterprise-beans>
- </ejb-jar>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<description>
This is Hello EJB example
</description>
<display-name>HelloBean</display-name>
<enterprise-beans>
<session>
<display-name>Hello</display-name>
<ejb-name>Hello</ejb-name>
<home>org.martin.common.communication.ejb.HelloHome</home>
<remote>org.martin.common.communication.ejb.Hello</remote>
<ejb-class>org.martin.server.communication.ejb.HelloEJB</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
(3)将Hello.jar放到JBOSS安装目录下的\server\default\deploy目录下,JBOSS支持热部署,因此不需要重启JBOSS,文件放入后,JBOSS的控制台中会打印,部署成功日志,如下所示:
08:43:52,859 INFO [EJBDeployer] Deployed: file:/C:/jboss/server/default/deploy/ Hello.jar |
4. 客户端测试
为了简单,这里用JavaSE客户端程序的方式调用EJB方法,代码如下
- package org.martin.client.communication.ejb
- public class HelloClient
- {
- @SuppressWarnings("unchecked")
- public static void main(String[] args)
- {
- Hashtable env = new Hashtable();
- env.put(Context.INITIAL_CONTEXT_FACTORY,
- "org.jnp.interfaces.NamingContextFactory");
- env.put(Context.PROVIDER_URL, "localhost:1099");
- env.put("java.naming.factory.url.pkgs",
- "org.jboss.naming:org.jnp.interfaces");
- try
- {
- Context ctx = new InitialContext(env);
- Object obj = ctx.lookup("Hello");
- HelloHome home = (HelloHome) javax.rmi.PortableRemoteObject
- .narrow(obj,HelloHome.class);
- Hello helloWorld = home.create();
- EjbMessage para=new EjbMessage();
- para.commandID=10000001;
- para.obj="hello";
- EjbMessage re=helloWorld.getHello(para);
- System.out.println(re.obj);
- helloWorld.remove();
- }
- catch(Exception e)
- {
- e.printStackTrace();
- System.out.println("Exception: " + e.getMessage());
- }
- }
- }
package org.martin.client.communication.ejb
public class HelloClient
{
@SuppressWarnings("unchecked")
public static void main(String[] args)
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
env.put(Context.PROVIDER_URL, "localhost:1099");
env.put("java.naming.factory.url.pkgs",
"org.jboss.naming:org.jnp.interfaces");
try
{
Context ctx = new InitialContext(env);
Object obj = ctx.lookup("Hello");
HelloHome home = (HelloHome) javax.rmi.PortableRemoteObject
.narrow(obj,HelloHome.class);
Hello helloWorld = home.create();
EjbMessage para=new EjbMessage();
para.commandID=10000001;
para.obj="hello";
EjbMessage re=helloWorld.getHello(para);
System.out.println(re.obj);
helloWorld.remove();
}
catch(Exception e)
{
e.printStackTrace();
System.out.println("Exception: " + e.getMessage());
}
}
}
执行客户端程序后,客户端程序控制台打印出“hello is echo by server”说明EJB方法调用成功。
5. 总结
这里简单描述了一个stateless的Session Bean的 DIY 过程,这里方法中使用了可序列化的Bean作为消息的载体。
在实际项目中,为了客户端调用、处理方便,可以在服务端将每个EJB用一个命令码进行关联,这时候客户端调用就只要指定这个命令码就可以,通过这个命令码去服务端查找EJB服务,调用完直接将结果返回给客户端。上面消息体中的commandID字段就可以作为这类命令码使用
实际项目中还可以对一个EJB进行封装,再增加消息ID来区分同一个EJB调用的不同操作,这种处理在实际项目中是非常常见的,因为不可能任何一个操作都定义一个EJB,一般是一个大功能(模块)定义一个EJB。客户端最关注的是参数和返回结果,因此EJB的通信流程等处理对客户端而言需要尽可能的透明。