拦截器不捕获 EJBAccessException

Interceptor does not catch EJBAccessException

我正在使用 Wildfly 12 (EE 8)。

我试图通过拦截器捕获 EJBAccessException 以将其作为我自己的异常类型重新抛出,但无济于事。我的拦截器中的代码在抛出时根本不会被调用。它确实有效并且确实捕获了其他异常,所以我不确定出了什么问题。关于这个 "internal" 问题,EJB 是否以某种方式无法识别我的拦截器,或者它是否可能仅在 Wildfly 自己的 AuthorizationInterceptor 被调用后才被调用?

我的ejb-jar.xml:

<interceptors>
    <interceptor>
        <interceptor-class>myExceptionInterceptor</interceptor-class>
    </interceptor>
</interceptors>
<assembly-descriptor>
    <interceptor-binding>
        <ejb-name>*</ejb-name>
        <interceptor-class>myExceptionInterceptor</interceptor-class>
    </interceptor-binding>
</assembly-descriptor>

我的 beans.xml 是空的,我也尝试将拦截器声明放在那里但没有效果。

我的拦截器:

@Throws
@Interceptor
@Priority(Interceptor.Priority.APPLICATION) // Tried playing with this too
public class myExceptionInterceptor implements Serializable {
    @AroundInvoke
    public Object check(InvocationContext invocationContext) throws Exception {
    try {
        return invocationContext.proceed();
    }
    catch (javax.ejb.EJBAccessException e) {
        //rethrow as own exception
    }

我关于 EJB 安全性的 standalone.xml 部分内容:

<default-security-domain value="jaspitest"/>
<default-missing-method-permissions-deny-access value="true"/>

我的拦截器绑定:

@Inherited
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target( {ElementType.METHOD, ElementType.TYPE} )
public @interface Throws {}

我正在调用它的示例 bean:

@Stateless
public class UserService extends Service<User> {
   @RolesAllowed(Role.ADMIN)
   public void delete() {}
}

这不起作用,因为您的拦截器需要访问其关联业务方法所具有的同一个 javax.ejb.EJBContext 对象。请参阅 EJB 规范 (3.2) 的 §4.7.2 中的 Table 2。

因此,在调用您的拦截器之前应用安全检查。

解决这个问题的唯一方法是将您的服务包装在一个不安全的外观中,并将拦截器应用于它。

我认为可以用容器拦截器来解决这个问题。 Container interceptors - 将下一个 xml 放入 jboss-ejb3.xml 文件中:

<jboss xmlns="http://www.jboss.com/xml/ns/javaee"
   xmlns:jee="http://java.sun.com/xml/ns/javaee"
   xmlns:ci ="urn:container-interceptors:1.0">

<jee:assembly-descriptor>
    <ci:container-interceptors>
        <jee:interceptor-binding>
            <ejb-name>*</ejb-name>
            <interceptor-class>YOUR FULLY QUALIFIED INTERCEPTOR CLASS GOES HERE</interceptor-class>
        </jee:interceptor-binding>            
    </ci:container-interceptors>
</jee:assembly-descriptor></jboss>
  • 将 jboss-ejb3.xml 复制到您的部署中 resources/META-INF。
  • 像链接的 WildFly 文档中的示例一样简单地创建拦截器

您可以在调用 invocationContext.proceed() 后捕获 EJBAccessException。