泽西岛忽略ExceptionMapper

时间:2019-06-30 02:47:56

标签: jackson jax-rs jersey-2.0 auto-value

我做了一个ExceptionMapper来捕获和记录所有异常,例如:

@Provider
public class CatchAllExceptionsMapper implements ExceptionMapper<Throwable> {
    private static final Logger LOG = LoggerFactory.getLogger(CatchAllExceptionsMapper.class);
    @Override
    public Response toResponse(Throwable exception) {
        LOG.error("Exception not catched!", exception);
        return Response.serverError().build();
    }
}

它捕获了我的代码抛出的Exception,但是如果我发送的JSON值请求在创建对象时抛出了IllegalStateException,则该ExceptionMapper被忽略,我得到400 Bad Request响应。

有趣的是,这个Response不是传统的Tomcat HTML格式的Response,它只是纯文本。它只是说:

  

无法构造`com.example.vo.AutoValue_Customer $ Builder`的实例,问题:名字为空或为空。在[来源:(org.glassfish.jersey.message.internal.ReaderInterceptorExecutor $ UnCloseableInputStream);行:14,列:1]

我以为这可能是泽西岛的短路,但是我的@PreMatching ContainerRequestFilter是事先执行的,所以我真的不知道为什么400响应不是传统的HTML响应来自Tomcat。

为什么会这样?我该怎么做才能发现并返回我自己的回复?

1 个答案:

答案 0 :(得分:0)

如Paul Samsotha在评论中所述,JacksonFeature包中的jersey-media-json-jackson定义了一些ExceptionMapper,例如JsonMappingExceptionJsonParseException。解决方案是创建我们自己的,在ResourceConfig中注册它们,最后注册JacksonFeature,否则将不起作用。

例如

@Provider
@Priority(1) // hack for overriding other implementations.
public class JsonMappingExceptionMapper implements ExceptionMapper<JsonMappingException> {
    @Override
    public Response toResponse(JsonMappingException exception) {        
        return Response.status(Status.BAD_REQUEST).build();
    }
}


@Provider
@Priority(1) // hack for overriding other implementations.
public class JsonParseExceptionMapper implements ExceptionMapper<JsonParseException> {
    @Override
    public Response toResponse(JsonParseException exception) {        
        return Response.status(Status.BAD_REQUEST).build();
    }
}

public class MyResourceConfig extends ResourceConfig {
    public MyResourceConfig() {
        register(CatchAllExceptionsMapper.class);
        register(JsonMappingExceptionMapper.class);
        register(JsonParseExceptionMapper.class);
        register(JacksonFeature.class);
    }
}