语境

我们使用注释为javax.ws.rs.ext.ExceptionMapper<Exception>@javax.ws.rs.ext.Provider来处理所有异常。在内部,此ExceptionMapper区分不同类型的异常,以确定向客户端显示哪些信息。

对于javax.validation.ConstraintViolationException,我们返回有关哪个字段无效以及原因为何的其他信息。

问题

我们只是从TomEE 1.7.2 JAX-RS切换到TomEE 7.0.0-SNAPSHOT webprofile

通过使用TomEE 1.7.2 JAX-RS,我们使用了openejb.jaxrs.providers.auto=true系统属性,我们的ExceptionMapper被自动找到并使用。

使用TomEE 7.0.0-SNAPSHOT webprofile,不再需要该属性即可从自动发现中受益。

但是,还发现了org.apache.cxf.jaxrs.validation.ValidationExceptionMapper,现在它是ExceptionMapper的首选javax.validation.ConstraintViolationException。我们自己的ExceptionMapper无法运行,因此客户端无法获得有关验证期间出了什么问题的信息。

我们自己的ExceptionMapper<Exception>仍然可以处理所有其他异常。

我已经尝试过的

“复制”专门的ExceptionMapper
我在资源旁边放置了自己的javax.ws.rs.ext.ExceptionMapper<javax.validation.ConstraintViolationException>,希望它优先于CXF代码。
org.apache.cxf.jaxrs.validation.ValidationExceptionMapper仍然优先。

更新:原来,这确实可以解决问题。我不知道为什么我的初始测试不起作用。

通过ValidationExceptionMapper禁用system.properties
TomEE 7.0.0-SNAPSHOTchangelog中,我注意到了

TOMEE-1336支持classname.activated =自动发现的提供程序的true / false

看着相应的changeset,我希望我可以通过添加禁用org.apache.cxf.jaxrs.validation.ValidationExceptionMapper org.apache.cxf.jaxrs.validation.ValidationExceptionMapper.activated = false
到我们的system.properties

这仍然没有效果。

问题

  • 这是CXF还是TomEE行为?
  • 我们如何配置哪个ExceptionMapper优先?
  • 最佳答案

    现在花一些时间,但认为它是规范所需要的,但是您可以通过设置cxf.jaxrs.skip-provider-scanning=true来禁用它。

    它完全禁用了自动提供程序,包括已扫描的自动提供程序,但是您可以用openejb-jar.xml控制所需的自动提供程序-IMHO肯定是最好,最安全的解决方案,否则您将依赖大量使用的库和容器设置。

    没有优先级afaik,因为使用了异常层次结构。

    编辑:遗漏了一部分:您需要执行ExceptionMapper{ValidationException},否则CXF优先级高于您自己的优先级(例外情况不太明确)
    编辑2:https://issues.apache.org/jira/browse/TOMEE-1656为激活的支持

    07-26 04:49