跟我学EJB 分布式编程技术——实现JNDI检索的基类和EJBHandle实现实例
- 格式:pdf
- 大小:256.72 KB
- 文档页数:14
目录1.1EJB WebService相关实现技术及应用实例 (2)1.1.1EJB作为Web服务端点技术概述 (2)1.1.2EJB WebService实例应用 (5)1.1.3编译该EJB组件 (9)1.1.4将该EJB组件发布为WebService组件 (9)1.1.5导出EJBBean组件 (17)1.1.6对客户和服务器进行设置 (17)1.1.7查看该客户端的*.jar文件 (20)1.1.8发布该EAR文件 (22)1.1.9查看所部署的结果 (22)1.1EJB WebService相关实现技术及应用实例1.1.1EJB作为Web服务端点技术概述1、JAX-RPC快速入门(1)JAX-RPC(Java API for XMLbased RPC)顾名思义,它是一种远程方法调用(或者说远程过程调用),那么它和其它的远程方法调用(RPC, COM,CORBA,RMI)有什么区别呢?(2)一般的远程方法调用的结构我们看一般的远程方法调用的结构,如下图所示。
综合比较常用的远程方法调用技术,它们有以下的共性:●在客户端和服务端有通用编程接口;●在客户端有Stub,在服务端有Tie(有的叫Skeleton);●客户端和服务端有专门的协议进行数据传输。
对于通用接口的描述,比如CORBA有IDL of CORBA,Java RMI有Java RMI interface in RMI,对于XMLbased RPC来说,IDL就是WSDL(Web服务描述语言)。
那么XMLbased RPC来说,什么是这个结构中的"传输协议",当然是SOAP,SOAP消息通过以传输文本为基础的协议(HTTP、SMTP、FTP)为载体来使用的,也就是说,SOAP消息的传输建立在HTTP传输协议之上。
(3)JAX-RPC的构架从上图可以看出,客户端调用的是JAX-RPC服务端点(Service Endpoint),这个服务端点是通过WSDL语言描述的。
菜鸟学EJB(⼀)——第⼀个实例EJB⽤了那么长时间了,从来没写过关于它的东西,挺对不住它的。
今天先写⼀个简单的⼩实例,虽然⼩但是却能体现出EJB的核⼼——分布式。
我们可以将业务逻辑的接⼝跟实现部署到⼀台机器上,将调⽤它们的客户端部署到另⼀台机器上。
⾄于为什么要⽤分布式,今天不做讨论,以后再细说。
先来看接⼝:package com.tjb.ejb;public interface MyEjb {String helloEjb ();}接下来是对接⼝的具体实现:package com.tjb.ejb;import javax.ejb.Remote;import javax.ejb.Stateless;import javax.jws.WebMethod;import javax.jws.WebService;@Stateless@Remote@WebServicepublic class MyEjbBean implements MyEjb {public String helloEjb() {return "Hello EJB";}}然后编写⼀个客户端来通过接⼝调⽤我们的实现:package com.tgb.ejb;import javax.naming.InitialContext;import javax.naming.NamingException;import com.tjb.ejb.MyEjb;public class MyEjbClient {public static void main(String[] args) throws NamingException {InitialContext ctx = new InitialContext();MyEjb ejb = (MyEjb) ctx.lookup("MyEjbBean/remote");String hello = ejb.helloEjb();System.out.println(hello);}}客户端实例化⼀个上下⽂对象,然后通过其lookup⽅法查找远程实现,最后调⽤具体的⽅法。
目录1.1跟我学EJB 分布式编程技术——WebLogic下的事务JTA编程实例 (2)1.1.1利用JTA实现事务管理相关的技术 (2)1.1.2了解JTS 和JTA之间的关系和差别 (6)1.1.3JDBC事务编程实现 (8)1.1.4BEAN管理的事务实现及实例 (10)1.1.5容器管理的事务 (12)1.1.6在Java中的事务处理技术编程的实例 (17)1.1跟我学EJB 分布式编程技术——WebLogic下的事务JTA编程实例1.1.1利用JTA实现事务管理相关的技术1、事务概述(1)什么是事务事务是一种手段,用于保证一系列的数据库操作能够准确的完成并将在(分布式)资源上的一组操作被当作一个工作单元(unit)。
以保证数据的准确性、可靠性、一致性和时效性。
(2)应用的领域在贸易、金融和电子商业领域中,多数大的企业应用依赖于递送它们的商务的事务处理功能。
鉴于当今商务对灵活性的要求,在建造、部署和维护企业级别的分布式应用中,事务处理占据的是其中最复杂的部分之一。
(3)为什么要使用事务完成一个操作可能需要使用多步使用事务的一个重要原因,是完成一个操作可能需要使用多步,其中任何一步操作的失败,都希望全部回滚。
提供事务的目的在于简化既要求可靠性又要求可用性的应用程序结构,特别是那些需要同时访问共享数据的应用程序。
以银行转账系统为例:如下图所示,转账是通过两步完成的,但转账时,提款是正确的,但存款错误,总的账目将发生不平衡,显然这是不允许的。
因为一个将资金从一个帐户转移到另一个帐户的Enterprise beans 中可能有一系列方法,它们是借记第一个帐户,贷记第二个帐户。
你想将整个操作作为一个单元处理,但是,如果借记后、贷记前出现故障,借记就会滚回。
不必处理数据库故障恢复和维护数据库完整性利用事务管理,可以把应用程序的工作分成若干称为事务的工作单元。
此时,开发者就不必处理数据库故障恢复和维护数据库完整性这样的复杂问题。
1.1JBuilder MessageBean (2)1.1.1WebLogic (2)1.1.2JBuilder MDB (5)1.1.3 (10)1.1.4 (15)1.1.5MapMessage (18)1.1JBuilder MessageBean1.1.1WebLogic"Connection Factory""File Stores""JMS Servers""JMS Queue"1WebLogic MDB1Connection Factories JNDI EBussFactory2File Stores EBussStore c:\temp3JMS Servers EbussJMSServer4JMS Queue JNDI EBussJMSQueueJNDI EBussJMSQueue21EBussFactoryName JNDI EBussFactory2EBussJMSFileStore c:\temp3JMSEBussJMSServer4EBussJMSQueue JNDI EBussJMSQueueJNDI3Topic JNDI 1"JMS Topic..."Name EBussJMSTopicJNDI Name EBussJMSTopicJNDI"Create" "Apply"1.1.2JBuilder MDB1JBuilder Project JMSEJBBean2EJB ModuleJMSMDBBean 2.03MDB1)MDB MDBEJBBean2)Message Selector3)DestinName EBussJMSQueueJNDIJNDI weblogic mydomain> JMS Servers> MyJMSServer> JMS Destinations JNDI Name1)Destination Type javax.jms.Queue2)Connect Factory Name EBussFactory weblogic JMS connectionfactory JNDI Name3)Transaction type Bean BeanMessageJMSSQL-92 SQL WHERE item<message-selector>item = 'Financial Analysis' OR item ='Gardening'</message-selector>MDBEJBBean.javapackage jmsejbbean;import javax.ejb.*;import javax.jms.*;import javax.naming.*;public class MDBEJBBean implements MessageDrivenBean, MessageListener { MessageDrivenContext messageDrivenContext;public void ejbCreate() throws CreateException {/**@todo Complete this method*/}public void ejbRemove() {/**@todo Complete this method*/}public void onMessage(Message msg) {/**@todo Complete this method*/}public void setMessageDrivenContext(MessageDrivenContext messageDrivenContext) { this.messageDrivenContext = messageDrivenContext;}}4MDB onMessage(Message msg)MessageListenerEJBpublic void onMessage(Message msg){try{if (msg instanceof TextMessage){TextMessage text=(TextMessage)msg;System.out.println(text.getText()); //}else{System.out.println("error text");}}catch(JMSException e) //TextMessage.getText() {}}5Project6ejb-jar.xml MDB7weblogic-ejb-jar.xml1.1.31jmsejbbeanClient QueueSend2package jmsejbbeanClient;import java.io.*;import java.util.Hashtable;import javax.jms.*;import javax.naming.*;public class QueueSend{// Defines the JNDI context factory.public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";// Defines the JMS context factory.public final static String JMS_FACTORY="EBussFactory";//weblogic JMS Connection Factories JNDI Namepublic final static String QUEUE="EBussJMSQueueJNDI";//weblogic mydomain> JMS Servers> MyJMSServer> JMS Destinations JNDI Nameprivate QueueConnectionFactory queueConnectionFactory;private QueueConnection queueConnection;private QueueSession queueSession;private QueueSender queueSender;private Queue queue;private TextMessage textMessage;public void init(Context ctx, String queueName) throws NamingException, JMSException{//1weblogic JMS Connection Factories JNDI NameConnection FactoriesqueueConnectionFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);//2Connection Factories QueueConnection queueConnection = queueConnectionFactory.createQueueConnection();//3QueueConnection QueueSessionqueueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);//4weblogic mydomain> JMS Servers> MyJMSServer> JMS Destinations JNDI Name Queuequeue = (Queue) ctx.lookup(queueName);//5QueueSession QueueSenderqueueSender = queueSession.createSender(queue);//QueueSession TextMessagetextMessage = queueSession.createTextMessage();//6queueConnection.start();}public void send(String message) throws JMSException{textMessage.setText(message); //7queueSender.send(textMessage); //8}public void close() throws JMSException{queueSender.close();queueSession.close();queueConnection.close();}private void readAndSendMessageText(QueueSend messageQueueSendClient) throws IOException, JMSException{BufferedReader msgStream = new BufferedReader(new InputStreamReader(System.in));String userMessageText=null;boolean isQuitNow = false;do{ //'quit'System.out.print("('quit'): ");userMessageText=msgStream.readLine();if (userMessageText != null && userMessageText.trim().length() != 0){messageQueueSendClient.send(userMessageText);System.out.println("JMS:"+userMessageText+"\n");isQuitNow = userMessageText.equalsIgnoreCase("quit");}}while (! isQuitNow);}public static void main(String[] args) throws IOException, JMSException,javax.naming.NamingException{QueueSend messageQueueSendClient = new QueueSend();InitialContext ic =messageQueueSendClient.getInitialContext("t3://localhost:7001");messageQueueSendClient.init(ic, QUEUE);messageQueueSendClient.readAndSendMessageText(messageQueueSendClient);messageQueueSendClient.close(); //9}private static InitialContext getInitialContext(String url) throws NamingException{Hashtable env = new Hashtable();env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);env.put(Context.PROVIDER_URL, url);return new InitialContext(env);}}1.1.41*.jar2WebLogic3WebLogic"JMSMDBBean"4JMS5MDB1)weblogic JMS Connection Factories JNDI NameConnection Factories2)Connection Factories QueueConnection3)QueueConnection QueueSession4)weblogic mydomain> JMS Servers> MyJMSServer> JMS DestinationsJNDI Name Queue5)QueueSession QueueSender6)QueueSession TextMessage7)8)9)10)1.1.5MapMessage1TextMessageMapMessageMapMessage2package jmsejbbeanClient;import java.io.*;import java.util.Hashtable;import javax.jms.*;import javax.naming.*;public class QueueSend{// Defines the JNDI context factory.public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";// Defines the JMS context factory.public final static String JMS_FACTORY="EBussFactory";//weblogic JMS Connection Factories JNDI Namepublic final static String QUEUE="EBussJMSQueueJNDI";//weblogic mydomain> JMS Servers> MyJMSServer> JMS Destinations JNDI Nameprivate QueueConnectionFactory queueConnectionFactory;private QueueConnection queueConnection;private QueueSession queueSession;private QueueSender queueSender;private Queue queue;private MapMessage mapMessage;public void init(Context ctx, String queueName) throws NamingException, JMSException{//1weblogic JMS Connection Factories JNDI NameConnection FactoriesqueueConnectionFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);//2Connection Factories QueueConnection queueConnection = queueConnectionFactory.createQueueConnection();//3QueueConnection QueueSessionqueueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);//4weblogic mydomain> JMS Servers> MyJMSServer> JMS Destinations JNDI Name Queuequeue = (Queue) ctx.lookup(queueName);//5QueueSession QueueSenderqueueSender = queueSession.createSender(queue);//QueueSession TextMessagemapMessage = queueSession.createMapMessage();//6queueConnection.start();}public void send() throws JMSException{mapMessage.clearBody(); //7mapMessage.setInt("userID", 1234); //name=" userID"Value= 1234 mapMessage.setString("userName", "");mapMessage.setInt("userAge", 30);mapMessage.setString("userEMAIL", "abc@");queueSender.send(mapMessage); //8System.out.println("JMS");}public void close() throws JMSException{queueSender.close();queueSession.close();queueConnection.close();}public static void main(String[] args) throws IOException,JMSException,javax.naming.NamingException{QueueSend messageQueueSendClient = new QueueSend();InitialContext ic =messageQueueSendClient.getInitialContext("t3://localhost:7001");messageQueueSendClient.init(ic, QUEUE);messageQueueSendClient.send();messageQueueSendClient.close(); //9}private static InitialContext getInitialContext(String url) throws NamingException {Hashtable env = new Hashtable();env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);env.put(Context.PROVIDER_URL, url);return new InitialContext(env);}}3package jmsejbbean;import javax.ejb.*;import javax.jms.*;import javax.naming.*;public class MDBEJBBean implements MessageDrivenBean, MessageListener {MessageDrivenContext messageDrivenContext;public void ejbCreate() throws CreateException {/**@todo Complete this method*/}public void ejbRemove() {/**@todo Complete this method*/public void onMessage(Message msg){try{if (msg instanceof TextMessage){TextMessage text=(TextMessage)msg;System.out.println(text.getText()); //}else if (msg instanceof MapMessage){MapMessage mapMessage = (MapMessage) msg;System.out.println("");System.out.println("ID"+mapMessage.getInt("userID"));System.out.println(""+mapMessage.getString("userName"));System.out.println(""+mapMessage.getInt("userAge"));System.out.println("Email"+mapMessage.getString("userEMAIL"));}else{System.out.println("");}}catch(JMSException e) //TextMessage.getText(){}/***Bean context*/public void setMessageDrivenContext(MessageDrivenContext messageDrivenContext) {this.messageDrivenContext = messageDrivenContext;}}45WebLogic。
1.1J2EE架构师——J2EE EJB分布式组件编程应用技术培训课程
1、课程简介
本课程是J2EE架构师中的第一阶段—— J2EE EJB分布式组件编程技术,学员经过二个阶段的课程模块的系统培训学习,将帮助软件开发人员最终掌握J2EE企业开发技术和系统构架、设计模式以及后台数据库。
2、学习基础
掌握JAVA核心技术,JAVA高级应用开发,J2EE Web应用开发技术。
3、培训目标
掌握和使用Workshop、JBuilder和WebLogic等工具开发和部署J2EE多层、松耦合和可重用的企业级组件。
内容涵盖EJB的三大组件技术,同时还将涉及JNDI、RMI和J2EE的安全验证授权,综合应用等方面的内容。
实现企业级多层分布式应用的RMI、JNDI和EJB组件技术(三种EJB Bean)以及J2EE 的安全/事务/资源连接服务,能够独立完成J2EE四层构架的项目开发。
4、培训时间
6天,48学时。
上午(8:30--11:45,4学时)、下午(1:00--4:15,4学时),人手一机,边学边练、逐步深入!强调独立实践操作能力、实例讲解。
5、培训内容(可根据具体学员的基础进行适当调整,以便学员能够快速接受)。
目录1.1无状态的SessionBean等EJB的安全访问实现实例 (2)1.1.1访问EJB的安全技术 (2)1.1.2在Weblogic服务器的控制台中创建出用户和用户组 (4)1.1.3在EJB配置描述文件中定义安全角色和对该角色进行授权 (8)1.1.4管理委托策略及应用实例 (14)1.1无状态的SessionBean等EJB的安全访问实现实例1.1.1访问EJB的安全技术1、安全性技术概述(1)安全策略安全是每个企业级应用不可缺少的一部分,一个安全应用必须考虑安全策略,以保护应用中每一个层次上的资源。
比如可以将企业应用系统划分为企业员工、供应商、合作伙伴等不同的安全域,对这些安全区域采用不同的安全策略下面,我们将会详细讨论如何建立一个安全的WebLogic的应用。
这里,我们将介绍EJB 容器中一个标准的安全特性。
一个安全的EJB应用应该利用EJB容器提供的安全服务,集成到应用的安全模型中去。
(2)基于容器的安全在J2EE的环境中,组件的安全是由他们各自的容器来负责的,组件的开发人员几乎可以不用或者很少在组件中添加有关安全的代码。
这种安全逻辑和业务逻辑相对独立的架构,使得企业级应用系统有更好的灵活性和扩展性。
因为J2EE的规范要求J2EE产品必须为应用程序开发者提供两种形式的基于容器的安全性-----说明性的安全性和可编程的安全性。
2、说明性的安全性(1)部署描述符文件说明性的安全性是通过安全结构描述的方式来代表应用程序的安全需求,安全结构一般包括安全角色,访问控制和验证要求等。
在J2EE平台中的EJB组件的部署描述符将充当说明性的安全性的主要工具。
部署描述符是组件开发者和应用程序部署者或应用程序组装者之间的交流工具。
应用程序的开发者用它来表示应用中的安全需求,应用程序部署者或应用程序组装者将安全角色与部署环境中的用户和组映射起来。
(2)标准的EJB安全模型安全角色标准的EJB安全模型基于EJB配置描述器中的设置以及简单的编程安全接口。
目录1.1EJBWebService+WebLogic客户端程序及实例 (2)1.1.1在JSP页面中(Web服务器为WebLogic)WebService中的方法 (2)1.1.2编译本实例项目 (7)1.1.3创建访问该WebService方法的Web应用 (7)1.1.4编译该项目并最后再打包该项目为*.war文件 (11)1.1.5编译该项目和部署该Web应用程序 (17)1.1EJBWebService+WebLogic客户端程序及实例1.1.1在JSP页面中(Web服务器为WebLogic)WebService中的方法1、新建一个project,其名称为UserEJBWebServiceInWebLogic2、将该WebLogic的WebService导入点击“OK”按钮,然后在下面的对话框内Toolkit中选择WebLogic类型(因为使用我们的WebService的客户端的Web服务器为WebLogic)。
在Module Type栏中选择Client Module Only(因为现在是创建WebService的客户端程序)在Client Module栏中输入客户端模块的名称:UserEJBWebServiceWLClient点击“OK”按钮后,将出现如下的结果页3、根据WSDL的URL导入对应的客户代理程序右击“From URL”,然后选择“Add”菜单后将创建出缺省的代理程序4、编辑设置该代理程序Display Name:EJBWebServiceWebLogicClientInput WSDL File:http://127.0.0.1:7001/SessionEJBWebService/SessionEJBWebService?WSDL (前面所发布的EJB SessionBean的 WebService的WSDL的URL地址)User Name:无Password:无将自动出现WebService程序中的方法5、设置客户程序的其它方面的特性●点击上面的“Client”,选择“Overwrite existing Client Jar”项目,其它则采用缺省的设置值。
目录1.1跟我学EJB 分布式编程技术——实体EJB组件编程技术及实现实例 (2)1.1.1实体EJB组件相关技术及应用 (2)1.1.2实体组件类相关的接口定义 (6)1.1.3实体类型EJB组件持久性管理方式 (7)1.1.4CMP实体Bean编程 (7)1.1.5BMP实体Bean编程 (12)1.1.6复合主键类及应用实例 (15)1.1跟我学EJB 分布式编程技术——实体EJB组件编程技术及实现实例1.1.1实体EJB组件相关技术及应用1、实体组件的基本特征(1)实体组件概述实体组件代表存储在外部介质中的持续(Persistence)对象或者已有的企业应用系统资源。
简单地说:一个实体组件可以模拟为数据库表中的一行记录,多个客户端应用能够以共享方式访问表示该数据库记录的实体组件。
依赖于EJB容器提供的事务服务,多个客户端应用能够在保持数据库记录的一致性和完整性前提下实现对数据资源的共享。
实体类型EJB组件的生命期相对较长并且其状态是持续的。
只要实体组件代表的数据库记录存在,该组件对象实例就一直存在,即使EJB容器崩溃,实体组件仍然具有生命力。
按照实体类型EJB组件持久性的实现形式,可以将实体组件分为容器管理持久性(Container-Managed Persistence,CMP)和组件管理持久性(Bean-Managed Persistence,CMP)两种类型。
在CMP类型EJB 组件的实现代码中,组件程序设计人员不需要为组件的持久性控制方法编写任何数据库操作的代码,而是在组件组装和部署过程中由部署工具自动创建。
如果要创建BMP类型EJB组件,则组件程序设计人员需要为所有持久性方法编写控制代码。
与数据库中的数据记录相对应,每个实体类型EJB组件包含一个主键(Primary Key)标识,该标识与组件代表的数据库记录主键相同。
客户端应用可以利用该主键定位EJB容器中的实体组件对象实例,进而定位组件代表的数据库记录。
目录1.1跟我学EJB 分布式编程技术——消息Bean编程实现相关的技术及应用 (2)1.1.1消息Bean编程相关的技术及应用 (2)1.1.2Java消息服务---JMS概述 (4)1.1.3消息驱动的EJB 组件及实现示例 (8)1.1.4MDB体系结构及相关的API (10)1.1.5MDB客户程序接口及程序示例 (14)1.1.6点对点消息队列模式及应用 (15)1.1.7点对点消息队列模式编程的步骤 (18)1.1.8发布-订阅消息模式及应用实例 (19)1.1跟我学EJB 分布式编程技术——消息Bean编程实现相关的技术及应用1.1.1消息Bean编程相关的技术及应用1、概述(1)消息服务消息服务是一种在分布式应用之间提供消息传递服务的软件,具有可靠、异步、宽松结合、语言中立、平台中立的特点,而且通常是可配置的。
利用异步方式,我们从中获得额外的好处是程序之间有一个宽松的耦合,发送请求的代码和响应请求的代码是分离的。
不同的客户端把消息发送到同一个指定的目的地;然后,接收者(Receiver)从目的地分离出消息并显示出来。
(2)利用消息实现松散耦合的应用消息服务是一个功能强大的范例,它用于构建健壮的、灵活的、松散耦合的、可伸缩的应用程序。
有一些商业消息服务产品,如 WebSphere MQ、Sonic、Fiorano、JBossMQ 和SpiritWave。
就像 JDBC 对于数据库一样,JMS 是消息的中间件--它使得应用程序可以通过统一的接口访问不同的消息队列产品,这个接口提供了像 Connection 、 Topic 和 Message 这样的抽象。
(3)实现原理它的实现原理是:对发送者和接收者之间传递的消息进行封装,并在分布式消息客户程序结合的位置加上一个软件处理层。
消息服务为消息的客户程序提供了一个接口,这个接口隔离了底层的消息服务,使得各种不同的客户程序能够通过一个友好的编程接口方便地通信。
目录1.1Oracle9i数据库系统下的CMP20组件开发实例 (2)1.1.1三种JDBC连接方式的系统配置 (2)1.1.2配置WebLogic连接池和数据源 (3)1.1.3在JBuilderX中配置Oracle9i的JDBC驱动程序库 (12)1.1.4在JBuilder中创建2.0版的Oracle 9i的CMP EJB (15)1.1Oracle9i数据库系统下的CMP20组件开发实例1.1.1三种JDBC连接方式的系统配置1、weblogic 方式,使用weblogic的jDriver属性值URL:jdbc:weblogic:oracleDriver Classes: weblogic.jdbc.oci.DriverProperties (key=value):user=xixipassword=hahaserver=your_tnsname注意:●需要安装oracle的客户端,其中的your_tnsname是你在Oracle客户端中配置的指向oracle服务器的本地服务名●startWeblogic.cmd中Path变量加入.\bin\oci817_82、oracle JDBC的thin方式----Thin方式是纯java的,它和数据库实例打交道属性值URL:jdbc:oracle:thin:@193.0.0.5:1521:ora8Driver Classes: oracle.jdbc.driver.OracleDriverProperties (key=value): user=xixipassword=hahadll=ocijdbc8protocol=thin注意:●不需要安装oracle的客户端, ora8为你要连接的数据库的SID●startWeblogic.cmd中Path变量加入.\bin\oci817_8,●同时在CLASSPATH中加入$ORACLE_HOME\jdbc\lib\classes12.zip或classes111.zip,使之能找到oracle的JDBC类。
1.1跟我学EJB 分布式编程技术——分布式多层体系结构1、分布式多层应用模型(1)J2EE 概述互联网以及电子商务技术的普及和发展,推动着企业信息系统的构建和更新进程。
为了缩短企业信息系统的设计和开发周期、降低构建企业信息系统的成本、在已有系统中对变化的商务规则迅速地做出反映,Sun公司制订了Java2 SDK Enterprise Edition(J2EE)规范,定义基于组件的方式设计、开发、组装和部署企业应用系统的各个组成部分。
J2EE规范定义了分布式多层应用系统模型、组件重用策略、一致化的安全模型以及灵活的事务控制策略等,使得独立软件提供商(ISV)能够以比以前更快的速度向市场推出具有用户适应性的客户解决方案。
另外,平台独立、基于组件技术的J2EE解决方案不受软件产品类型和不同应用环境的制约。
在实际构建的企业信息系统中,需要根据J2EE规范定义的分布式多层应用模型将不同性质和用途的组件部署到不同类型的应用服务器中。
J2EE规范根据企业信息系统各个组成部分在功能上的区别,将整个应用系统划分为客户层、中间层(其中可包括WEB层、业务层)和企业信息系统层三层结构,如下图所示。
各个应用层分别配置在不同类型的应用服务器中。
基于J2EE规范划分的企业应用系统逻辑层(2)企业应用系统的各个逻辑层客户层客户层用于与企业信息系统的用户进行交互以及显示根据特定商务规则进行计算后的结果。
基于J2EE 规范的客户端可以是基于WEB的,也可以是不基于WEB的独立(Stand Alone)应用程序。
在基于WEB的J2EE客户端应用中,用户在客户端启动浏览器后,从WEB服务器中下载WEB层中的静态HTML页面或由JSP 或Servlets动态生成的HTML页面。
在不基于WEB的J2EE客户端应用中,独立的客户端应用程序可以运行在一些基于网络的系统中,比如手持设备或汽车电话等。
同样,这些独立的应用也可以运行在客户端的Java Applet中。
1.1EJB ----SessionBean (2)1.1.1WebLogic J2EE (2)1.1.2EJB (5)1.1.3EJB JNDI (11)1.1.4EJB (14)1.1EJB ----SessionBean1.1.1W ebLogic J2EEJBuilderX SessionBean WebLogic J2EEBean BeanServlet JSP JavaBean Bean1Project StatelessSessionBeanProject2EJBJBuilder EJB Bean JBuilder EJB, *.jar EJB Bean EJBEJB EJB Bean1File---New Object Gallery"Enterprise""EJB""EJB Module""OK""Create empty EJB Module""Next"2EJBEJB EJB mathSessionBean3"OK"EJB1.1.2EJB1Create EJB"Session Bean"2EJBmathSessionEJBBean statelessEJB Bean Bean1)EJB Bean2)BeanEJB Bean3)Bean Bean BeanBean BeanBEA WebLogic ServerBeanEJB4)BeanBean BeanBean Bean ""Bean 02Bean0Bean3EJB1EJB Add---Method----View Bean Source Bean Open DD Editor----Rgenerate Interfaces----Bean HomeRemote2getSummary int int digitOne, int digitTwo remote1)2)JBuilder SessionBeanBean ComponentComponentHome ----HomeComponentBean ---BeanComponent ----ComponentLocalHome ----homeComponentLocal ----3mathSessionEJB.javapackage statelesssessionbean;import javax.ejb.*;import java.util.*;import java.rmi.*;public interface mathSessionEJB extends javax.ejb.EJBObject {public int getSummary(int digitOne, int digitTwo) throws RemoteException; }4mathSessionEJBHome.java Homepackage statelesssessionbean;import javax.ejb.*;import java.util.*;import java.rmi.*;public interface mathSessionEJBHome extends javax.ejb.EJBHome {public mathSessionEJB create() throws CreateException, RemoteException; }5mathSessionEJBBean.java Beanpackage statelesssessionbean;import javax.ejb.*;public class mathSessionEJBBean implements SessionBean{SessionContext sessionContext;public void ejbCreate() throws CreateException{ //SessionBean ejbCreate()}public void ejbRemove(){}public void ejbActivate(){}public void ejbPassivate(){}public void setSessionContext(SessionContext sessionContext) {this.sessionContext = sessionContext;}public int getSummary(int digitOne, int digitTwo){return null;}}4EJBgetSummary View Bean sourcegetSummarypublic int getSummary(int digitOne, int digitTwo) {return (digitOne+digitTwo);}1.1.3EJB JNDIEJB EJB DD Source Weblogic-ejb-jar.xmlEJB Weblogic EJB1ejb-jar.xmlSun J2EE EJB EJBEJB<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "/dtd/ejb-jar_2_0.dtd"><ejb-jar><enterprise-beans><session><display-name>mathSessionEJBBean</display-name><ejb-name>mathSessionEJBBean</ejb-name><home>statelesssessionbean.mathSessionEJBHome</home><remote>statelesssessionbean.mathSessionEJB</remote><ejb-class>statelesssessionbean.mathSessionEJBBean</ejb-class><session-type>Stateless</session-type><transaction-type>Container</transaction-type></session></enterprise-beans><assembly-descriptor><container-transaction><method><ejb-name>mathSessionEJBBean</ejb-name><method-name>*</method-name></method><trans-attribute>Required</trans-attribute></container-transaction></assembly-descriptor></ejb-jar>EJB ejb-name mathSessionEJBBeanEJB home statelesssessionbean.mathSessionEJBHomeEJB remote statelesssessionbean.mathSessionEJBEJB ejb-class statelesssessionbean.mathSessionEJBBeanEJB session-type StatelessEJB transaction-type Container Containerjar EJB DDEJBHome Remote BeanSession BeansEntity BeansCMP primary keyEJBEJBEJBMethod-mapping ()2Weblogic-ejb-jar.xmweblogic-ejb-jar.xmlEJB WebLogic<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN' '/servers/wls810/dtd/weblogic-ejb-jar.dtd'><weblogic-ejb-jar><weblogic-enterprise-bean><ejb-name>mathSessionEJBBean</ejb-name><jndi-name>mathSessionEJBBean</jndi-name></weblogic-enterprise-bean></weblogic-ejb-jar>mathSessionEJBBean EJB ejb-name mathSessionEJBBean JNDI jndi-name mathSessionEJBBeanWebLogic mathSessionEJBBean EJB EJBJNDImathSessionEJBBean EJB1.1.4EJB1EJB2EJB1J2EEJ2EE Java (JAR)XML2"/"J2EEJ2EEJ2EE ejb EJB EJB J2EE3JBuilder EJB Test Client EJBEJB1File--New Enterprise EJB"EJB Test Client"2Application3statlessSBclient SessionBean EJBmathSessionEJBBeanTestClient"Generate Logging message" "Next"45EJBpackage statlessSBclient;i mport statelesssessionbean.*; //EJBJBimport javax.naming.*;import java.util.Properties;import javax.rmi.PortableRemoteObject;public class mathSessionEJBBeanTestClient extends Object{private mathSessionEJBHome mathSessionEJBHomeObject = null;private mathSessionEJB mathSessionEJBRemote = null; //Remote//Construct the EJB test clientpublic mathSessionEJBBeanTestClient() {initialize();}public void initialize() {try {//get naming contextContext context = getInitialContext();//look up jndi nameObject ref = context.lookup("mathSessionEJBBean");//look up jndi name and cast to Home interfacemathSessionEJBHomeObject = (mathSessionEJBHome) PortableRemoteObject.narrow(ref, mathSessionEJBHome.class);//RemotemathSessionEJBRemote = mathSessionEJBHomeObject.create();//Remote EJBBeanSystem.out.println("EJB10+20="+mathSessionEJBRemote.getSummary(10,20));}catch(Exception e) {e.printStackTrace();}}private Context getInitialContext() throws Exception {String url = "t3://localhost:7001";String user = null;String password = null;Properties properties = null;try {properties = new Properties();properties.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");properties.put(Context.PROVIDER_URL, url);if (user != null) {properties.put(Context.SECURITY_PRINCIPAL, user);properties.put(Context.SECURITY_CREDENTIALS, password == null ? "" : password);}return new InitialContext(properties);}catch(Exception e) {System.out.println("Unable to connect to WebLogic server at " + url);System.out.println("Please make sure that the server is running.");throw e;}}//----------------------------------------------------------------------------// Utility Methods//----------------------------------------------------------------------------public mathSessionEJBHome getHome() {return mathSessionEJBHomeObject;}//Main methodpublic static void main(String[] args) {mathSessionEJBBeanTestClient client = new mathSessionEJBBeanTestClient();// Use the getHome() method of the client object to call Home interface// methods that will return a Remote interface reference. Then// use that Remote interface reference to access the EJB.}}2)JNDI EJB HomegetInitialContext()JNDIHome RMI StubContext context = getInitialContext();Object ref = context.lookup("mathSessionEJBBean");mathSessionEJBHomeObject = (mathSessionEJBHome) PortableRemoteObject.narrow(ref, mathSessionEJBHome.class);3)narrow()narrow()EJB EJBPortableRemoteObject.narrow()CORBA EJB stubstubWebLogic RMI/T3Stubnarrow()RMI/T3narrow()4)Home create()create()create()Home Bean4Project5EJB1EJBEJBEJB2BeanBean EJB EJB6Bean1Beancreate()EJB BeanBean Bean2Bean BeanEJBSessionContext setSessionContext()SessionContextEJB EJBEJB ejbCreate()Bean ejbCreate()ejbCreate()ejbCreate()EJB EJB Bean EJB Bean ejbRemove()3EJB WebLogic ServerBeanBeanWebLogic ServerBean EJBEJB4webLogic-ejb-jar.xml5)<initial-beans-in-free-pool>10</initial-beans-in-free-pool>EJBBean EJBBean6)<max-beans-in-free-pool>100</max-beans-in-free-pool>Bean EJBBean Bean BeanBeanBean<max- beans-in-free-pool >WebLogic ServerBeanBean WebLogic Server5<max-beans-in-free-pool>BeanBean<max-beans-in-free-pool>Bean。
目录1.1实现JNDI检索的基类和EJBHandle实现实例 (2)1.1.1实现JNDI检索的基类 (2)1.1.2修改访问EJB组件的客户端程序 (4)1.1.3执行该客户程序 (7)1.1.4使用EJB Bean的句柄来保存EJB (7)1.1.5句柄应用程序例 (13)1.1.6HomeHandle的应用例 (13)1.1.7应用Handle所应该注意的问题 (14)1.1实现JNDI检索的基类和EJBHandle实现实例1.1.1实现JNDI检索的基类1、概述由于在EJB的客户程序中的JNDI检索是非常标准的,所以我们在应用中没有必要每次写客户程序的时候都重新编写它,而可以专门做一个类GetEJBHomeByJNDI,放在文件GetEJBHomeByJNDI.java中。
实际的客户程序可以从该类来继承和派生。
2、GetEJBHomeByJNDI.java文件(1)添加一个类(2)包名称为statlessSBclient,类名称为GetEJBHomeByJNDI(3)编程该类的代码package statlessSBclient;import javax.naming.*;import java.util.Properties;import javax.rmi.PortableRemoteObject;public class GetEJBHomeByJNDI extends Object {public Context getInitialContext() throws Exception {String url = "t3://localhost:7001";/* String user = null;String password = null;*/String user = "WebAdmin";String password = "12345678";Properties properties = null;try{properties = new Properties();properties.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");properties.put(Context.PROVIDER_URL, url);if (user != null) {properties.put(Context.SECURITY_PRINCIPAL, user);properties.put(Context.SECURITY_CREDENTIALS, password == null ? "" : password);}return new InitialContext(properties);}catch(Exception e){System.out.println("Unable to connect to WebLogic server at " + url);System.out.println("Please make sure that the server is running.");throw e;}}}1.1.2修改访问EJB组件的客户端程序package statlessSBclient;import statelesssessionbean.*;import javax.naming.*;import java.util.Properties;import javax.rmi.PortableRemoteObject;public class mathSessionEJBBeanTestClient extends GetEJBHomeByJNDI{private mathSessionEJBHome mathSessionEJBHomeObject = null;private mathSessionEJB mathSessionEJBRemote = null; //声明一个Remote接口对象//Construct the EJB test clientpublic mathSessionEJBBeanTestClient(){initialize();}public void initialize(){try{Context context = getInitialContext(); //get naming contextObject ref = context.lookup("mathSessionEJBBean"); //look up jndi name//look up jndi name and cast to Home interfacemathSessionEJBHomeObject = (mathSessionEJBHome) PortableRemoteObject.narrow(ref, mathSessionEJBHome.class);//下面为创建出Remote主接口类型的对象mathSessionEJBRemote = mathSessionEJBHomeObject.create();//下面为利用Remote主接口类型的对象对EJBBean类中的方法进行访问System.out.println("利用无状态会话EJB计算10+20的结果="+mathSessionEJBRemote.getSummary(10,20));System.out.println("获得无状态会话EJB中的环境变量"+mathSessionEJBRemote.getEJBEnvItem());}catch(Exception e){e.printStackTrace();}}public void executeRemoteCallsWithDefaultArguments(mathSessionEJB mathSessionEJBObject){if (mathSessionEJBObject == null){return ;}try{mathSessionEJBObject.getSummary(0 ,0);}catch(Exception e){e.printStackTrace();}}//----------------------------------------------------------------------------// Utility Methods//----------------------------------------------------------------------------public mathSessionEJBHome getHome(){return mathSessionEJBHomeObject;}//Main methodpublic static void main(String[] args){mathSessionEJBBeanTestClient client = new mathSessionEJBBeanTestClient();// Use the getHome() method of the client object to call Home interface// methods that will return a Remote interface reference. Then// use that Remote interface reference to access the EJB.}}1.1.3执行该客户程序1.1.4使用EJB Bean的句柄来保存EJB1、关于句柄的使用在某些情况下,EJB客户机也许希望把EJBObject引用保留到永久的设备上,以便将来使用,甚至在另一个程序中使用。
EJB规范定义了句柄(Handle)的概念。
作为一个序列化对象,据柄中封装了足够的信息,以便重建对EJBObject的引用。
2、获得句柄或者重建EJB Bean的引用只能用remote接口的句柄来重新建立Bean的引用。
你不能用句柄来创建Bean本身。
如果另一个进程删除了Bean,或者系统崩溃或关闭,删除了Bean的实例,则当应用程序试图用句柄重新建立对Bean的引用时会抛出异常。
当你不确定Bean的实例是否依然存在的时候,你可以不用remote接口的句柄。
而是保存Bean的home接口的句柄,在以后要用的时候再通过调用create方法或finder方法重新创建Bean对象。
在客户创建了Bean的实例以后,就能够用getHandle()方法来获得实例的句柄。
一旦拥有的句柄,就能够将它写到文件里面去。
在以后的时间,客户可以读这个文件,将读出来的对象转化为句柄类型。
然后,就可以在句柄上调用的getEJBObject方法来获得bean的引用。
最后再将getEJBObject方法返回的值转化为合适的类型。
为了取得句柄,程序员可以调用EJBObject接口中的getHandle()方法,该方法返回一个javav.ejb.Handle实例。
为了重建EJBObject的引用,可以使用Handle接口的getEJBObject()方法。
3、在客户程序中根据Bean的Remote对象获得并保存其句柄javax.ejb.Handle mathSessionEJBHander=null;…mathSessionEJBRemote = mathSessionEJBHomeObject.create();mathSessionEJBHander=mathSessionEJBRemote.getHandle();4、将句柄序列化到某一文件中FileOutputStream fileOutputStream = new FileOutputStream("mathSessionEJBHander.ser");ObjectOutputStream objectOutputStream= new ObjectOutputStream(fileOutputStream);objectOutputStream.writeObject(mathSessionEJBHander);objectOutputStream.flush();objectOutputStream.close();此时在磁盘文件中的项目目录下将产生出一个mathSessionEJBHander.ser文件。