在 Java EE 前端方法中处理服务层异常 [英] Handling service layer exception in Java EE frontend method

查看:22
本文介绍了在 Java EE 前端方法中处理服务层异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我维护一个 Web 应用程序,该应用程序有一个带有 JSF 标记 <f:event 的页面.我在服务类中重写了一个方法,以便它抛出业务异常.但是,当业务异常被抛出时,它不会被托管 bean 捕获,并且异常会显示在页面上.似乎我的代码 try/catch 不起作用.

I maintain a web application that have a page with the JSF tag <f:event. I have rewrote a method in a service class for it to throw a business exception. However, when the business exception is thrown, it isn't caught in managed bean and the exception is showed on the page. Seems that my code try/catch doesn't work.

在 XHTML 中:

<f:event listener="#{resourceBean.init(enrollment)}" type="preRenderView" />

Managed Bean 中的监听器方法:

Listener method in Managed Bean:

private boolean canCreateResource;

public void init(Enrollment enrollment) {
    (...)

    try {
        canCreateResource = resourceService.canCreateResource(enrollment);
    } catch (BusinessException e) {
        canCreateResource = false;
    }
}

服务类中的方法:

public boolean canCreateResource(Enrollment enrollment) {
    if (...) {
        if (mandateService.isCoordinator(user, course)) {
            return true;
        } else {
            throw new BusinessException("Undefined business rule.");
        }
    }

    return false;
}

根据我在其他网站上阅读的内容,我想我必须实现一些 JSF 的处理程序类.但是哪个以及如何?

From what I read on other sites, I suppose I have to implement some JSF's handler class. But which and how?

已编辑

OBS 1:BusinessException 类扩展了 RuntimeException 类.

OBS 1: The BusinessException class extends RuntimeException class.

OBS 2:创建属性 canCreateResource 来控制按钮的呈现.

OBS 2: The attribute canCreateResource was created to control the render of a button.

推荐答案

因为你抛出了 RuntimeException 来自 EJB.

It's because you threw a RuntimeException from an EJB.

当此类 RuntimeException 未使用 @ApplicationException,然后 EJB 容器会将其包装在 javax.ejb.EJBException 中并重新抛出它.这样做是因为运行时异常通常仅用于指示代码逻辑中的错误,即程序员的错误而不是最终用户的错误.你知道,NullPointerExceptionIllegalArgumentExceptionIndexOutOfBoundsExceptionNumberFormatException 和朋友们.这允许 EJB 客户端对此类运行时异常有一个包罗万象的点,例如 catch (EJBException e) { 服务层或我们使用它的方式存在错误!}

When such RuntimeException is not annotated with @ApplicationException, then the EJB container will wrap it in an javax.ejb.EJBException and rethrow it. This is done so because runtime exceptions are usually only used to indicate bugs in code logic, i.e. programmer's mistakes and not enduser's mistakes. You know, NullPointerException, IllegalArgumentException, IndexOutOfBoundsException, NumberFormatException and friends. This allows the EJB client to have one catch-all point for such runtime exceptions, like catch (EJBException e) { There's a bug in the service layer or in the way how we are using it! }

如果您尝试过 catch (Exception e) 并检查了实际的异常,那么您就会注意到这一点.

If you had tried catch (Exception e) and inspected the actual exception, then you'd have noticed that.

相应地修复您的 BusinessException 类以添加该注释,然后它将被识别为真正的应用程序异常,而不是包装在 EJBException 中:

Fix your BusinessException class accordingly to add that annotation, it will then be recognized as a real application exception and not be wrapped in an EJBException:

@ApplicationException(rollback=true)
public class BusinessException extends RuntimeException {
    // ...
}

请注意,如果您抛出非RuntimeException,那么您仍然需要使用rollback=true 显式地保留注释,因为默认情况下它不会执行回滚,与没有注释的 RuntimeException 相反.

Do note that in case you throw an non-RuntimeException, then you still need to keep the annotation on that, explicitly with rollback=true, because by default it wouldn't perform a rollback, on the contrary to a RuntimeException without the annotation.

@ApplicationException(rollback=true)
public class BusinessException extends Exception {
    // ...
}

总结:

  1. RuntimeException 从事务性 EJB 方法抛出将执行完全回滚,但异常将被包装在 EJBException 中.
  2. RuntimeException@ApplicationException 来自事务性 EJB 方法,只有在显式设置 rollback=true 时才会执行完全回滚.
  3. Exception 来自事务性 EJB 方法将不会执行完全回滚.
  4. Exception with @ApplicationException 来自事务性 EJB 方法仅在显式设置 rollback=true 时执行完全回滚.
  1. RuntimeException thrown from transactional EJB method will perform full rollback, but exception will be wrapped in EJBException.
  2. RuntimeException with @ApplicationException from transactional EJB method will only perform full rollback when rollback=true is explicitly set.
  3. Exception from transactional EJB method will not perform full rollback.
  4. Exception with @ApplicationException from transactional EJB method will only perform full rollback when rollback=true is explicitly set.

请注意,@ApplicationException 继承自自定义异常的所有子类,因此您无需对所有子类重复.最好将它作为一个抽象类.另请参阅下面链接的相关问题中的示例.

Note that @ApplicationException is inherited over all subclasses of the custom exception, so you don't need to repeat it over all of them. Best would be to have it as an abstract class. See also the examples in the related question linked below.

这篇关于在 Java EE 前端方法中处理服务层异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆