分享
 
 
 

利用EjbProxy

王朝java/jsp·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

利用EjbProxy

调用远程EJB的一个简单有效的class

摘要:

这个技巧告诉你如何利用EjbProxy,它提供了一些事例,调用远程EJB并不是直接与你的代码接合执行一个特殊的EJB。

By Gorsen Huang

Translator Biggie

如果你经常采用EJB开发,你或许从客户机程序那里写代码访问EJB或者写代码访问其它EJB。通常情况下,执行这些代码仅需要一些很少的变化。一个好的程序员大多数情况下处理这个问题用拷贝和贴切。然而,拷贝和贴切几次后,它会变得让人烦燥。 那就是为什么我决定开发一个class让它帮我去做,我把它叫EjbProxy,用它使得代码保持干净和整洁,这个类在调用任何EJB都不需要知道EJB的jndi name,并且可以在客户端或是EJB里使用它。

你必须遵循4种基本的措施来调用EJB

1. 创建一个jndi上下文(initial context)

2. 在上下文中查找EJB name (look up the EJB name in context)

3. 取得EJB对像

4. 通过home对像的create()方法创建EJB实例对像

1-3步具体实施如下:

InitialContext ctx = new InitialContext (prop);

Object home = ctx.lookup(beanName);

EJBHome obHome =

(EJBHome) PortableRemoteObject.narrow (home, EJBHome.class);

如你所见,你得到一个EJB name Object不需要知道具体的执行细节,除用jndi查找以外。

第4步不是简单易懂的,当你试图用home对像去创建一个EJB 对像的时候,一旦EJBHome 接口没有定义create()方法时,你就不能通过home 对象调用create() 方法,只是实际上执行EJB实现这个方法。

作为一个可行的解决方法,你可以定义一个接口去继承EJB home并且声名create()方法,然后你可以简单的用home对像的这个接口并且访问create()方法。然而,这种方法有一个缺点:它需要所有的EJB实现这个接口,从任意的home接口中,调用你想调用的create()方法。

一个更好的解决方法是你可以使用java的反射能力(关于反射API的详细资料请参考Resources)利用reflection (反射)API你可以用Class.forname方法加载指定的class,然后访问getDeclaredMethod()方法重新声明class,你能用Method.invoke 执行这种方法。

以下代码是使用反射从home对像中获得EJB的实例对像:

Method m = obHome.getClass().getDeclaredMethod("create", new Class[0]);

Object objRemote = m.invoke (obHome, new Object[0]);

Object obj = PortableRemoteObject.narrow(objRemote, theClass);

即,这段程序片断是从home对像中得到class,并且通过访问getDeclaredMethod()以create()方法名称获得create's Method对像。此外用invoke()方法执行create方法,返回EJB的实例对像。

The EjbProxy class

EjbProxy class,源代码EjbProxy.java,为你处理这些令人讨厌的细节。

用EjbProxy相当简单,首先创建一个EjbProxy对像,你可以传递参数,例如用initial context 工厂 和provider URL去创建initial context对像。然后访问getObj()方法用jndi查找EJB获得EJB实例对像。注意,当你从一个EJB调用另一个EJB涉及到名称时,你可能需要填加lookup name的一个环境字符串,例如java.comp/env/.

例子程序download 它将显示给你如何用EjbProxy去调用一个EJB。测试目的,我同样执行一个EJB,名字叫EjbProxyExample,它有一个pulbic 方法

public String hello (String name) throws RemoteException;

这个方法传入一个名称字符串并且返回一个”hello”组成的字符串变量,EjbProxy的jndi名称例子如下:com.javaworldtip.ejbproxyexample.EjbProxyExample,假设你用weblogic在本地的7001端口去构造和发布EJB, EjbProxyExample,客户端代码:

EjbProxy myproxy = new EjbProxy ("weblogic.jndi.WLInitialContextFactory",

"t3://localhost:7001");

EjbProxyExample obj = (EjbProxyExample)myproxy.getObj

("com.javaworldtip.ejbproxyexample.EjbProxyExample");

//now get "Hello, World!" string and show it

String strHello = obj.hello("World");

System.out.println (strHello);

如果你用这个EJB调用同一服务器内部的另一个EJB的话,代码如下:

EjbProxy myproxy = new EbjProxy ();

EjbProxyExample obj = (EjbProxyExample)myproxy.getObj

("com.javaworldtip.ejbproxyexample.EjbProxyExample ");

如果你已经在部署文件中指定了EjbProxyExample,你就可以直接用getObj()方法:

EjbProxyExample obj =

(EjbProxyExample) myproxy.getObj ("java:comp/env/EjbProxyExmaple");

How it works(它是如何工作的)

你可以扩展构造器或setContextProperties()方法;

public void setContextProperties (String initContextFactory,

String providerUrl,

String user,

String password)

{

_prop = new Properties ();

_prop.put (Context.INITIAL_CONTEXT_FACTORY, initContextFactory);

_prop.put (Context.PROVIDER_URL, providerUrl);

if (user != null)

{

_prop.put(Context.SECURITY_PRINCIPAL, user);

if (password == null)

password = "";

_prop.put(Context.SECURITY_CREDENTIALS, password);

}

}

所有的参数都是创建initContext的环境,包括initcontext工厂,provider URL,用户名,密码,如果你用这个类在同一容器中重新得到EJB,你可以简单的传入null或是干脆不用理睬他们。

现在,让我们看一看在我们的代理类中的重要方法,getObj()

public Object getObj (String beanJndiLookupName) throws EJBException

{

try

{

EJBHome obHome = getHome (beanJndiLookupName);

//get the method of create

Method m = obHome.getClass().getDeclaredMethod("create", new Class[0]);

//invoke the create method

Object obj = m.invoke (obHome, new Object[0]);

return obj;

}

catch (NoSuchMethodException ne)

{

throw new EJBException (ne);

}

catch (InvocationTargetException ie)

{

throw new EJBException (ie);

}

catch (IllegalAccessException iae)

{

throw new EJBException (iae);

}

}

在getObj()方法里,唯一需要的参数就是EJB查找的jndi name,这个方法首先调用了一个gethome()方法来获得EJBhome对像,然后调用getDeclaredMethod()方法获得create方法。一旦create被捕获,你就可以调用它并取得EJB的实例对像,如果发生意外的话,将抛出一个异常。

你必须处理一些可能发生的异常,例如:如果EJB没有声名create方法,方法getDeclaredMethod()将抛出NoSuchMethodException异常,在这段程序中,各种各样的捕捉将通过创建新的EJBException来处理这些可能发生的异常,这个方法,程序调用getObj()方法必须抛出EJBException并且适当的处理。

以下那些在getOjb()方法的getHome()方法代码如下:

public EJBHome getHome (String beanJndiLookupName) throws EJBException

{

try

{

InitialContext ctx = null;

if (_prop != null)

ctx = new InitialContext (_prop);

else

ctx = new InitialContext ();

Object home = ctx.lookup(beanJndiLookupName);

EJBHome obHome = (EJBHome)PortableRemoteObject.narrow (home, EJBHome.class);

return obHome;

}

catch (NamingException ne)

{

throw new EJBException (ne);

}

}

这个方法简单的限制了第一步到第三步调用EJB方法,我用getHome()方法正确得到我想要的home对像。I.e你想得到EJB对像,并且迟些后调用它的方法(例如调用create方法创建一个session bean)

Extend EjbProxy

针对一些情况,你可能想继承EjbProxy,例如:假设EJB’s create()方法没有任何输入参数,你可以简单的通过继承这个类用getObj去处理大多数情况:

public Object getObj (String beanJNDILookupName, Class[] classes, Object[]

objects) throws EJBException;

在方法内部,当调用getDeclaredMethod() 和invoke()方法应用额外参数:

Method m = obHome.getClass().getDeclaredMethod("create", classes);

Object obj = m.invoke (obHome, objects);

你可以通过扩展这个类去执行任意EJB方法:

public Object executeMethod (String methodName, Class[] classes, Object[]

objects) throws EJBException;

methodName是执行方法名,在获得EJB对像之前,你可能需要在类中隐藏EJB对像。然后用类似过程修改getObj方法。

Simplify your everyday coding

利用java的反射机制,你可以用普通的柔韧性的EjbProxy,来调用本地的或是远程的或是另一个EJB,如你所见,你可以用EjbProxy 或是扩展它去实例化和调用EJB。

Resources

Obtain the source file for this tip:

http://www.javaworld.com/javaworld/javatips/javatip118/EJBProxyTip.zip

Sun's Enterprise JavaBeans information:

http://java.sun.com/products/ejb

Sun's Java Reflection API documentation:

http://java.sun.com/products/jdk/1.1/docs/guide/reflection/

Also see "Make an EJB from Any Java Class with Java Reflection," Tony Loton (JavaWorld, December 2000):

http://www.javaworld.com/jw-12-2000/jw-1215-anyclass.html

For more EJB articles, check out JavaWorld's Topical Index:

http://www.javaworld.com/channel_content/jw-ejbs-index.shtml

For more articles on JNDI, visit our Topical Index:

http://www.javaworld.com/channel_content/jw-jndi-index.shtml

View all previous Java Tips and submit your own:

http://www.javaworld.com/javatips/jw-javatips.index.html

Learn Java from the ground up in JavaWorld's Java 101 column:

http://www.javaworld.com/javaworld/topicalindex/jw-ti-java101.html

Java experts answer your toughest Java questions in JavaWorld's Java Q&A column:

http://www.javaworld.com/javaworld/javaqa/javaqa-index.html

Sign up for JavaWorld's free weekly email newsletters:

http://www.idg.net/jw-subscribe

You'll find a wealth of IT-related articles from our sister publications at IDG.net

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有