【问题标题】:Passing @ApplicationException through multiple EJB modules通过多个 EJB 模块传递 @ApplicationException
【发布时间】:2014-09-09 11:08:38
【问题描述】:

我有一个包含以下模块的 EJB 项目:

  • 一个处理 api 调用的 rest 模块
  • 为核心提供接口的 api 模块
  • 包含实际业务逻辑的核心模块

如果出现问题并且客户端应该收到错误,我将使用自定义异常,它们是 WebApplicationException 的子类并且已经包含适当的响应。

@ApplicationException(rollback = true)
public class InvalidParameterException extends WebApplicationException { }

永远不应该捕获这些异常。当将它注释为 ApplicationException 时,它不会被 glassfish 服务器日志拾取。到目前为止一切正常。

现在我有一种情况,核心模块包含另一个 EJB 模块,该模块包含它自己的 WebApplicationExceptions 子类,看起来与上面提到的类似。此异常按应有的方式传递给核心。然而,当这个异常被传递给 rest 模块时,它会被包装成一个javax.ejb.EJBTransactionRolledbackException,这会导致 glassfish 服务器日志记录所有这些异常,我想避免这种情况。

所以,@ApplicationException 注解只有在异常从 ejb 模块传递到核心模块时才有效,但是一旦进一步传递到其余模块,注解就不再生效。

有没有一种通过多个模块将异常作为 ApplicationException 传递的好方法?我知道我可以捕获异常并再次将其作为 ApplicationException 重新抛出,但这会使代码膨胀很多,并且看起来不是一个很好的解决方案。有没有更好的办法?

编辑:一些示例代码

休息模块:

@Path("/someservice")
@Stateless
public class SomeResource {

    @EJB private SomeService someService;

    @GET
    @Produces("application/json")
    public Response someGetMethod() {
        this.someService.someMethod();
        return Response.ok().build();
    }
}

api 模块:

public Interface SomeService {
    public void someMethod();
}

核心模块:

@Stateless
public Class SomeServiceImpl implements SomeService {

    @EJB private ExternalEJB externalEJB;

    public void someMethod() {
        externalEJB.externalMethod();
    }
}

一个外部 EJB 模块。通过<type>ejb</type>包含在 pom.xml(核心模块)中

@Stateless
public class ExternalEJB {
    public void externalMethod() {
       throw new ExternalApplicationException();
    }
}

来自外部模块的异常:

@ApplicationException
public class ExternalApplicationException extends WebApplicationException {

    private static final long serialVersionUID = 1L;

    public ExternalApplicationException() {
        super(Response.serverError().build());
    }
}

【问题讨论】:

  • 我们经常使用@ApplicationExceptions,它们通过多个 EJB 调用正确冒泡,但除外。但是,我看到您的通知有 rollback = true - 因此 EJBTransactionRolledBackException 不正是您想要的吗?
  • 这是因为rest模块在EJB容器之外。一般来说,不幸的是,如果不处理 EJBException 的子类,则无法无缝链接 EJB 和 REST 调用,而在事务和安全性方面,REST 模块(作为 EJB 客户端)注定要处理。
  • @AlexanderLanger 我刚刚检查了这个。如果我删除rollback = true(默认为false),行为不会改变一点。
  • @Osw 我不确定我是否真的理解这一点。如果我从 EJB CORE 模块抛出异常并将其传递给 REST 模块,那么一切都很好。如果异常由 EJB 模块引发,传递给 EJB CORE 模块,然后传递给 REST 模块,它会被包装在 EJBTransactionRolledBackException 中。
  • 不确定我是否完全了解呼叫流程,但您可能想查看 stackoverflow.com/questions/15387346/… ,可能是您的情况。如果不是,那么一些代码 sn-ps 会提供更多信息,谁调用谁以及如何调用,没有业务逻辑,最小的简短自包含示例。

标签: jakarta-ee glassfish ejb jax-rs


【解决方案1】:

修改您的业务异常以扩展 EJBException 并在 REST 层中捕获为:

try {
   // my code
}
catch (MyCustomExceptionThatExtendsEJBException e) {
    // catch my exceptions.
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-13
    • 2020-01-25
    • 1970-01-01
    • 2014-11-04
    相关资源
    最近更新 更多