泽西岛无法抓住任何杰克逊的例外

时间:2016-01-05 15:24:53

标签: json exception jersey jackson exceptionmapper

对于我的REST api,我使用jersey和ExceptionMapper来捕获全局异常。 它适用于我的应用程序抛出的所有异常,但我无法捕获杰克逊抛出的异常。

例如,我的一个端点接受包含枚举的对象。如果请求中的Json有一个不在enum jersey中的值,则抛出此异常

Can not construct instance of my.package.MyEnum from String value 'HELLO': value not one of declared Enum instance names: [TEST, TEST2]
at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@5922e236; line: 3, column: 1] (through reference chain: java.util.HashSet[0]->....)

即使我已创建此映射器

@Provider
@Component
public class JacksonExceptionMapper implements ExceptionMapper<JsonMappingException> {
  @Override
  public Response toResponse(JsonMappingException e) {
    ....
  }
}

代码永远不会到达此映射器。

为了捕捉这些例外,我们还需要做些什么吗?

修改 注意:我有jus尝试不太通用而不是JsonMappingException我使用InvalidFormatException在这种情况下调用映射器。但我仍然不明白,因为InvalidFormatException扩展了JsonMappingException并且也应该被调用

2 个答案:

答案 0 :(得分:6)

有同样的问题。
问题是JsonMappingExceptionMapper在映射器之前启动。

实际的例外是 com.fasterxml.jackson .databind.exc.InvalidFormatException ,并且映射器定义 com.fasterxml.jackson .jaxrs.base.JsonMappingException ,因此它更具体的异常。
你看,Jersey的异常处理程序看起来找到最准确的处理程序(参见org.glassfish.jersey.internal.ExceptionMapperFactory#find(java.lang.Class,T))。

要覆盖此行为,只需禁用正在使用的映射器:

  1. 使用XML: <init-param> <param-name>jersey.config.server.disableAutoDiscovery</param-name> <param-value>true</param-value> </init-param>

  2. 使用代码:resourceConfig.property(CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true);其中resourceConfig的类型为org.glassfish.jersey.server.ServerConfig。


  3. 您也可以编写自己的特定映射器:

    public class MyJsonMappingExceptionMapper implements ExceptionMapper<JsonMappingException>
    

    但我认为这是一种过度杀戮。

答案 1 :(得分:0)

您好,现在似乎可以退出备用答案了,不需要禁用Jersey AUTO_DISCOVERY功能。

只需使用@Priority(1)注释对您自己的异常映射器进行注释。数字越小,优先级越高。由于杰克逊自己的映射器没有任何优先级注释,因此将执行您的优先级注释:

@Priority(1)
public class MyJsonMappingExceptionMapper implements ExceptionMapper<JsonMappingException>