EJB - 异常处理
EJB 是通常基于分布式环境的企业应用程序的一部分。 因此,除了可能发生的正常异常之外,还可能存在通信故障、安全权限、服务器故障等异常。
EJB 容器以两种方式考虑异常 −
应用程序异常 − 如果违反业务规则或执行业务逻辑时出现异常。
系统异常 − 任何非业务逻辑或业务代码引起的异常。 RuntimeException、RemoteException 都是SystemException。 例如,EJB 查找期间出错。 RuntimeException、RemoteException 都是SystemException。
EJB容器如何处理异常?
当应用程序异常发生时,EJB容器会拦截异常,但将异常返回给客户端。 除非在代码中通过 EJBContext.setRollBackOnly() 方法指定,否则它不会回滚事务。 如果发生应用程序异常,EJB 容器不会包装异常。
当系统异常发生时,EJB容器会拦截异常,回滚事务并启动清理任务。 它将异常包装到 RemoteException 中并将其抛出给客户端。
处理应用程序异常
应用程序异常通常在会话 EJB 方法中引发,因为这些方法负责执行业务逻辑。 应用程序异常应在业务方法的 throws 子句中声明,并在业务逻辑失败时抛出。
@Stateless public class LibraryPersistentBean implements LibraryPersistentBeanRemote { ... public List<Book> getBooks() throws NoBookAvailableException { List<Book> books = entityManager.createQuery("From Books").getResultList(); if(books.size == 0) throw NoBookAvailableException ("No Book available in library."); return books; } ... }
处理系统异常
系统异常随时可能发生,例如命名查找失败、获取数据时发生sql错误。 在这种情况下,此类异常应该包装在 EJBException 下并抛出回客户端。
@Stateless public class LibraryPersistentBean implements LibraryPersistentBeanRemote { ... public List<Book> getBooks() { try { List<Book> books = entityManager.createQuery("From Books").getResultList(); } catch (CreateException ce) { throw (EJBException) new EJBException(ce).initCause(ce); } catch (SqlException se) { throw (EJBException) new EJBException(se).initCause(se); } return books; } ... }
在客户端,处理 EJBException。
public class EJBTester { private void testEntityEjb() { ... try{ LibraryPersistentBeanRemote libraryBean = LibraryPersistentBeanRemote)ctx.lookup("LibraryPersistentBean/remote"); List<Book> booksList = libraryBean.getBooks(); } catch(EJBException e) { Exception ne = (Exception) e.getCause(); if(ne.getClass().getName().equals("SqlException")) { System.out.println("Database error: "+ e.getMessage()); } } ... } }