我需要一些帮助来了解 Websphere Liberty (18.0.0.1) 如何处理在 JAX-RS 端点调用中引发的异常。我正在使用 Liberty 功能jaxrs-2.0
,因此应该由 WLP 提供实现。
现在,我的应用程序有一个接受 JSON 有效负载的 POST HTTP 端点,我想为所有可能的错误客户端输入提供自定义错误消息。
这是一个以我期望的方式起作用的案例:
- 客户端发送
application/xml
而不是application/json
ClientErrorException
容器抛出了一个- 我可以使用我自己的异常映射器(实现
ExceptionMapper<WebApplicationException>
来处理这个异常(实际上是处理所有的 web 应用程序异常,我很好) - 这样我可以格式化错误消息,用 ID 标记错误,无论需要什么。那挺好的
这是对我不起作用的情况:
- 客户端发送
application/json
,但正文为空 - 在这种情况下,核心例外是
java.io.EOFException: No content to map to Object due to end of input
- 是的,这看起来很准确 - 现在我无法弄清楚 - WLP 不是将其包装
EOFException
成某种WebApplicationException
(我可以轻松处理),而是将异常问题包装成JaxRsRuntimeException
这里有几点:
- 我不想创建一个映射器实现
ExceptionMapper<JaxRsRuntimeException>
,因为该异常不是 JAX-RS 2.0 规范的一部分,我必须提供对 JaxRsRuntimeException 的导入并将应用程序与一些特定于 Liberty 的库连接。 - 一个可能的解决方案是让我的映射器实现一个通用
ExceptionMapper<RuntimeException>
和字符串检查,如果它发现类名“JaxRsRuntimeException”的异常,然后处理它。但这对我来说似乎不正确。
那么,在这种情况下,WLP 设计是否不会给我 WebApplicationException 呢?处理这种情况的优雅解决方案是什么?
谢谢
编辑:添加了源代码的某些部分。
REST 端点和资源方法:
@Path("/books")
public class BookEndpoint {
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response createBook(Book book, @Context UriInfo uriInfo) {
bookDao.create(book);
UriBuilder builder = uriInfo.getAbsolutePathBuilder();
builder.path(Integer.toString(book.getId()));
return Response.created(builder.build()).entity(book).build();
}
}
带有 JAXB 注释的实体:
@XmlRootElement
public class Book {
private int id;
private String title;
// getters, setters
}
异常堆栈跟踪:
com.ibm.ws.jaxrs20.JaxRsRuntimeException: java.io.EOFException: No content to map to Object duto end of input
at org.apache.cxf.jaxrs.utils.JAXRSUtils.toJaxRsRuntimeException(JAXRSUtils.java:1928)
at [internal classes]
at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:201)
at [internal classes]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.EOFException: No content to map to Object duto end of input
at org.codehaus.jackson.map.ObjectMapper._initForReading(ObjectMapper.java:2775)
at [internal classes]
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBodyReader(JAXRSUtils.java:1413)
at [internal classes]
... 48 more