Jersey 忽略 ExceptionMapper
Jersey ignores ExceptionMapper
我做了一个 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
s,但是如果我发送一个带有 JSON 值的请求,该值在我的对象创建时抛出 IllegalStateException
,这个 ExceptionMapper
被忽略,我得到 400 Bad Request
响应。
有趣的是这个响应不是传统的 Tomcat HTML 格式的响应,它只是纯文本。它只是说:
Cannot construct instance of `com.example.vo.AutoValue_Customer$Builder`, problem: First name is null or empty. at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 14, column: 1]
我认为这可能是 Jersey 短路,但是我的 @PreMatching
ContainerRequestFilter
是预先执行的,所以我真的不知道为什么 400
Response 不是传统的HTML 一个来自 Tomcat.
为什么会这样?我该怎么做才能抓住这个和 return 我自己的回应?
正如 Paul Samsotha 在评论中所述,jersey-media-json-jackson
包中的 JacksonFeature
定义了一些 ExceptionMapper
,例如 JsonMappingException
和 JsonParseException
。解决办法是自己创建,在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);
}
}
我做了一个 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
s,但是如果我发送一个带有 JSON 值的请求,该值在我的对象创建时抛出 IllegalStateException
,这个 ExceptionMapper
被忽略,我得到 400 Bad Request
响应。
有趣的是这个响应不是传统的 Tomcat HTML 格式的响应,它只是纯文本。它只是说:
Cannot construct instance of `com.example.vo.AutoValue_Customer$Builder`, problem: First name is null or empty. at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 14, column: 1]
我认为这可能是 Jersey 短路,但是我的 @PreMatching
ContainerRequestFilter
是预先执行的,所以我真的不知道为什么 400
Response 不是传统的HTML 一个来自 Tomcat.
为什么会这样?我该怎么做才能抓住这个和 return 我自己的回应?
正如 Paul Samsotha 在评论中所述,jersey-media-json-jackson
包中的 JacksonFeature
定义了一些 ExceptionMapper
,例如 JsonMappingException
和 JsonParseException
。解决办法是自己创建,在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);
}
}