如何将 CDI 拦截器优先于 JAX-RS ExceptionMapper
How to priorize CDI Interceptor over JAX-RS ExceptionMapper
我有一个使用以下方法管理其事务的 REST 网络服务:
@Inherited
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({METHOD, TYPE, FIELD, PARAMETER})
public @interface TransactionRequired {
}
@Interceptor
@TransactionRequired
public class TransactionRequiredInterceptor {
@Inject
private EntityManager entityManager;
@AroundInvoke
public Object manageTransaction(InvocationContext ctx) {
try {
..start transaction..
}
catch(Exception e) {
..rollback..
}
}
}
我也像这样映射我的例外情况:
@Provider
public class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException> {
@Override
public Response toResponse(RuntimeException exception) {
.. return some response..
}
}
问题是,假设抛出 RuntimeException(事务启动后),它会立即被 RuntimeExceptionMapper 拦截,事务永远不会回滚。
既然如此,我需要一种方法来优先处理 TransactionRequiredInterceptor..
Obs:使用@Transactional 不是一个选项,因为我需要在 Tomcat 8.
上部署
恕我直言,你问的没有意义。因为您的 JAX-RS 库不必通过拦截器实现异常映射。
但是您的 TransactionRequiredInterceptor
仍然可以通过使用 finally
块来响应异常 - 因为 JVM 始终(几乎)保证其执行。
总之,我怀疑这是否是个好主意。
首先,更好的方法是拥有额外的层(我们称之为 service
或 dao
)并拦截此类 class 方法。
其次,您可以 100% 确定您的事务管理实现存在大量错误。恕我直言,在您的情况下(CDI 和 Tomcat),最好的方法是 DeltaSpike,因为它已经为您提供了这样的 @Transactional
拦截器:org.apache.deltaspike.jpa.api.transaction.Transactional
。我亲自使用它并取得了巨大的成功。
顺便说一句:由于许多其他有用的功能,您也可以尝试 Apache DeltaSpike - 它们可以让您省去很多麻烦。
我有一个使用以下方法管理其事务的 REST 网络服务:
@Inherited
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({METHOD, TYPE, FIELD, PARAMETER})
public @interface TransactionRequired {
}
@Interceptor
@TransactionRequired
public class TransactionRequiredInterceptor {
@Inject
private EntityManager entityManager;
@AroundInvoke
public Object manageTransaction(InvocationContext ctx) {
try {
..start transaction..
}
catch(Exception e) {
..rollback..
}
}
}
我也像这样映射我的例外情况:
@Provider
public class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException> {
@Override
public Response toResponse(RuntimeException exception) {
.. return some response..
}
}
问题是,假设抛出 RuntimeException(事务启动后),它会立即被 RuntimeExceptionMapper 拦截,事务永远不会回滚。
既然如此,我需要一种方法来优先处理 TransactionRequiredInterceptor..
Obs:使用@Transactional 不是一个选项,因为我需要在 Tomcat 8.
上部署恕我直言,你问的没有意义。因为您的 JAX-RS 库不必通过拦截器实现异常映射。
但是您的 TransactionRequiredInterceptor
仍然可以通过使用 finally
块来响应异常 - 因为 JVM 始终(几乎)保证其执行。
总之,我怀疑这是否是个好主意。
首先,更好的方法是拥有额外的层(我们称之为 service
或 dao
)并拦截此类 class 方法。
其次,您可以 100% 确定您的事务管理实现存在大量错误。恕我直言,在您的情况下(CDI 和 Tomcat),最好的方法是 DeltaSpike,因为它已经为您提供了这样的 @Transactional
拦截器:org.apache.deltaspike.jpa.api.transaction.Transactional
。我亲自使用它并取得了巨大的成功。
顺便说一句:由于许多其他有用的功能,您也可以尝试 Apache DeltaSpike - 它们可以让您省去很多麻烦。