Ind*_*ght 7 java exception java-ee java-ee-6 ejb-3.1
在提出我的问题之前,只是关于EJB3.1异常的一些背景知识 -
应用程序例外包括
用户定义已检查或未检查的具有@ApplicationException批注的异常
所有已检查的例外
java.lang.Exception及它的子类异常,
除了java.rmi.RemoteException及它的子类异常   
系统例外包括
java.rmi.RemoteException和它的子类异常
所有未经检查的例外情况
java.lang.RuntimeException和它的子类异常
java.lang.Error及它的子类异常
以下是我在本书中读到的声明
在EJB系统中,客户端不会例外,当遇到此类异常时,这些异常不会按原样传递给客户端,而是在javax.ejb.EJBException中包含.
我的问题 -
IndoKnight,您Exception对Java EE框架中的语义如何工作的完美总结.
以下是两个唯一的"bean提供者"行,您和我需要了解Java EE中的异常:
根据您认为合适的任何类型的异常或错误,您的bean可以完全自由地恢复,相对于bean可能存在的其他约束.如果你从异常中恢复过来,那么恭喜 - 再也没有问题=)
例如,相关约束可能是"使用容器管理的事务划分的企业bean不得使用任何干扰容器事务划分边界的事务管理方法"来引用Java EE 7教程第48-2页(您是否愿意)要以编程方式设置容器管理事务的回滚,请使用EJBContext.setRollbackOnly()).
与任何类型的Java应用程序一样,您也不鼓励处理Throwable或Error从非常低的级别抛出.RuntimeException从理论上讲,它属于这一类,因为它如此着名地表示"开发者错误",就像"完全出乎意料" - 但我们都知道它不是.
基本上,一个意外的异常(运行时异常+我们假设来自其他人的其他东西)被认为是代码无法处理的,应该由服务器处理.服务器需要通过在日志中打印有关它的内容来处理"不可处理的"异常(参见EJB 3.2规范,第204页)(稍后我将详细介绍!).
你问(这是我相信或坚持的):
上面描述的所有应用程序异常是否应该由EJB直接抛给客户端?
是.并且事务(如果一个是活动的)不会回滚,除非你明确声明它应该通过使用的rollback属性ApplicationException.抛出异常的Java代码是很自然的事情.Java EE无意拆除此编程模型.所以继续,抛出你喜欢的已检查异常,强制客户端尝试捕获它们或将运行时异常标记为应用程序异常并抛出这些异常.快乐投掷!
如果在抛出到客户端之前将系统异常包装在javax.ejb.EJBException中,那么javax.ejb.EJBException是否被视为系统异常?
是的,但不是因为你提供的原因.要清楚,没有名为SystemException的类型.只是花哨的措辞来描述那些大多数那些没有想到的bean可能发生的异常,并且很可能,它们来自EJB容器.您的代码绝对不应该抛出EJBException.这样做可能只会阻碍服务器的思维.由于您不拥有代码,因此也不能将异常注释为@ApplicationException,它由Java EE API提供.您可以扩展EJBException,但将代码伪装成服务器代码库的一部分是没有任何意义的.最重要的是,由于EJBException扩展了RuntimeException,我认为将EJBException归类为"系统级异常"是安全的.
某些远程客户端将接收RemoteException而不是EJBException.
在一个巨大的企业项目中你甚至可能都没有意识到的拦截器,可能会吞下从你的方法抛出的异常,即使你从来没有计划让他这样做,也会提交活动事务.
我敢打赌,您认为使用Throwable.getCause()始终可以检索被 抑制的异常.请注意,EJB 3.2规范并未说明容器必须或应该保留对被抑制原因的引用.实际上,容器唯一要做的就是记录异常.然后,如果bean不是单例,则必须丢弃bean实例并且不再使用它.此外,如果bean是一个消息驱动的bean,那么只有那时才需要"包装".未指定如何"包装"异常.超级便携式酷代码也应该看看Throwable.getCause()方法和Throwable.getSuppressed().不要盲目期望在处理代码中始终找到原始异常.
返回void的异步方法(注释为@Asynchronous的公共会话bean方法)不能将异常传播到其客户端.因此,它们不得声明或抛出应用程序异常(请参阅EJB 3.2规范第82页).请注意,当您调用异步方法时,可能是服务器无法提供线程资源来为您的请求提供服务,如果是这样,他需要抛出一个.. EJBException(第48页)!
也来自这个问题:
当出现业务逻辑错误而不是系统错误时,应抛出应用程序异常.
有一个重要的区别:应用程序异常不会自动导致事务回滚.客户端有机会在抛出应用程序异常后进行恢复.
应用程序异常将发送到客户端,而不会重新打包为EJBException.因此,您可以使用它们来报告验证错误或业务逻辑问题,并且它们将到达客户端.
javax.ejb.EJBException延长RuntimeException所以是的,它是一个系统异常.与此相关的常见场景:如果您RuntimeException的应用程序代码中未被捕获,它将回滚.这是非常有用的默认行为.
| 归档时间: | 
 | 
| 查看次数: | 6816 次 | 
| 最近记录: |