170 likes | 323 Views
J2EE —— 第 25 章会话 bean 示例. 会话 bean 类. 实现 SessionBean 接口 定义为 public ,不能是 abstract 或 final 实现一个或多个 ejbCreate 方法 实现业务方法 含有一个没有参数的 public 构造函数 一定不能定义 finalize 方法. CartBean.java. public class CartBean implements SessionBean { public void ejbCreate(String person) throws CreateException {
E N D
会话bean类 • 实现SessionBean接口 • 定义为public,不能是abstract或final • 实现一个或多个ejbCreate方法 • 实现业务方法 • 含有一个没有参数的public构造函数 • 一定不能定义finalize方法
CartBean.java public class CartBean implements SessionBean { public void ejbCreate(String person) throws CreateException { if (person == null) { throw new CreateException("Null person not allowed."); } else { customerName = person; } customerId = "0"; contents = new Vector(); } public void addBook(String title) { contents.addElement(title); } public void removeBook(String title) throws BookException { boolean result = contents.removeElement(title); if (result==false){throw new BookException(title + "not in cart.");} } public Vector getContents() { return contents; } public CartBean() {} public void ejbRemove() {} public void ejbActivate() {} public void ejbPassivate() {} public void setSessionContext(SessionContext sc) {} }
ejbCreate方法 • Cart shoppingCart = home.create(“Duke DeEar1”); • EJB容器实例化该企业bean • EJB容器调用CartBean中合适的ejbCreate方法来初始化状态 • 一个企业bean必须有一个或多个ejbCrate方法 • 必须是public void • 参数必须是合法的RMI API类型 • 不能是static或final • 可以抛出CreateException或其它应用程序特有的异常
业务方法 • shoppingCart.addBook("The Martian Chronicles"); • shoppingCart.removeBook("Alice In Wonderland"); • bookList = shoppingCart.getContents(); • 方法名不能与EJB体系结构定义的方法名冲突 • 必须是public • 参数必须是合法的RMI API类型 • 不能是static或final • 可抛出自定义异常 • 可抛出EJBException,它被封装为RemoteException
Home接口 Cart shoppingCart = home.create(“Duke DeEarl”); public void ejbCreate(String person) throws CreateException public interface CartHome extends EJBHome { Cart create(String person) throws RemoteException, CreateException; } • 参数个数类型与ejbCreate方法相同 • 参数和返回类型必须是有效的RMI类型 • create返回企业bean的远程接口类型 • 必须throws:RemoteException, CreateException
远程接口 public interface Cart extends EJBObject { public void addBook(String title) throws RemoteException; public void removeBook(String title) throws BookException, RemoteException; public Vector getContents() throws RemoteException; } • 方法与企业bean中一致 • 签名与企业bean中相同 • 参数和返回值必须是有效的RMI类型 • 必须throws:RemoteException
处理异常 • 系统异常 • 得不到数据库连接、SQL插入失败、lookup失败等 • 容器可能销毁bean实例,客户端不能处理 • 回滚事务 • 程序异常 • 编码异常、预定义异常 • 客户端可以处理 • 不回滚事务
Web服务示例 • Web服务端点接口 public interface HelloService extends Remote { public String sayHello(String name) throws RemoteException; } • 无状态会话bean实现类 public class HelloServiceBean implements SessionBean { public String sayHello(String name) { return "Hello "+ name + " from HelloServiceBean"; } public HelloServiceBean() {} public void ejbCreate() {} public void ejbRemove() {} public void ejbActivate() {} public void ejbPassivate() {} public void setSessionContext(SessionContext sc) {} }
编译、打包、部署、运行 • asant build • wscompile • deploytool
访问环境项 public double applyDiscount(double amount) { try { double discount; Context initial = new InitialContext(); Context environment = (Context)initial.lookup("java:comp/env"); Double discountLevel = (Double)environment.lookup("Discount Level"); Double discountPercent=(Double)environment.lookup(“Discount Percent”); if (amount >= discountLevel.doubleValue()) { discount = discountPercent.doubleValue(); }else { discount = 0.00; } return amount * (1.00 - discount); } catch (NamingException ex) { throw new EJBException("NamingException: "+ ex.getMessage()); } }
比较企业bean • 有状态会话bean bookCart = home.create("Bill Shakespeare"); videoCart = home.create("Lefty Lee"); if (bookCart.isIdentical(bookCart)) { // true ... } if (bookCart.isIdentical(videoCart)) { // false ... } • 无状态会话bean:isIdentical返回true • 实体bean:isIdentical方法,或者: String key1 = (String)accta.getPrimaryKey(); String key2 = (String)acctb.getPrimaryKey(); if (key1.compareTo(key2) == 0) System.out.println("equal");
传递企业bean的对象引用 public class WagonBean implements SessionBean { SessionContext context; public void setSessionContext(SessionContext sc) { this.context = sc; } public void passItOn(Basket basket) { basket.copyItems(context.getEJBObject()); } • 不能传递this引用,因为它直接指向bean实例 • 只能通过getEJBObject传递bean的远程引用
使用计时器服务 • 不包括有状态会话bean • 实体bean每个实例有自己的计时器 • 无状态会话bean和消息驱动bean不然 TimerService timerService = context.getTimerService(); Timer timer = timerService.createTimer(intervalDuration,"created timer"); • 计时器取消 • 计时器到零,容器调用ejbTimeout • 删除实体bean实例时 • bean调用Timer接口的cancel方法 • getHandle返回TimerHandle,可序列化,getTimer恢复,但不能传递给远程客户端
获取计时器信息 public long getTimeRemaining(); public java.util.Date getNextTimeout(); public java.io.Serializable getInfo(); • 容器管理事务,ejbTimeout一般有属性RequiresNew,容器在调用它之前开始新的事务,如果事务回滚,容器将试着至少再调用ejbTimeout一次
TimerSessionBean示例 public class TimerSessionBean implements SessionBean, TimedObject { private SessionContext context; public TimerHandle myCreateTimer(long intervalDuration) { TimerService timerService = context.getTimerService(); Timer timer=timerService.createTimer(intervalDuration, "created timer"); } public void ejbTimeout(Timer timer) {System.out.println("ejbTimeout "); } public void setSessionContext(SessionContext sc) {context = sc; } public void ejbCreate() {} public TimerSessionBean() {} public void ejbRemove() {} public void ejbActivate() {} public void ejbPassivate() {} }