【问题标题】:How to handle unexpected exceptions in JAX-RS如何处理 JAX-RS 中的意外异常
【发布时间】:2013-01-11 19:37:00
【问题描述】:

我的技术堆栈是 Tomcat (servlet 3.0)、Jersey for JAX-RS、Spring 和 Hibernate。当出现意外错误时,例如 Hibernate 中的某些数据转换错误,我不希望客户端看到我的堆栈跟踪,以了解 Tomcat 默认尝试打印的那些异常。不过,我想记录这些异常,以便找出问题所在并进行修复。

我的第一次尝试是使用来自 JAX-RS 的 ExceptionMapper,并且天真地认为这可以解决我的问题。但后来我注意到 Jersey 抛出了它自己的异常,例如未映射的 url 是 com.sun.jersey.api.NotFoundExceptions。这会导致记录我不想要的 404 异常。更糟糕的是,客户端不再得到 404,而是状态码 500。

我可以为球衣抛出的异常创建异常映射器,但我可能会错过一些东西。有这样的最佳做法吗?

【问题讨论】:

    标签: java spring servlets jersey jax-rs


    【解决方案1】:

    Jersey 直接抛出的所有异常都是 WebApplicationException 的子类,所以如果你想全部捕获它们,只需为该类创建一个 ExceptionMapper 就可以了。

    【讨论】:

    • 我在 ExceptionMapper 中做什么?我是否必须复制 WebApplicationExceptions 的 JAX-RS 实现?
    • 好吧,没关系。我阅读了 WebApplicationException 的源代码,看起来它总是有一个正确的 Response 对象,所以我可以在 ExceptionMapper 中返回它。
    • 是的,您可以,但请记住,这将给出标准的 Jersey 响应,它是一个完整的 HTML 页面,可能不是您想要返回的,特别是如果您使用 Jersey 作为API 服务器而不是直接提供页面。您可以选择响应以获取所需的基本信息,然后根据需要重新格式化。
    【解决方案2】:

    看看这个页面:http://www.rexsl.com/rexsl-core/trap.html。它解释了如何/应该如何捕获 Web 应用程序中的所有运行时异常。 ExceptionMapper 的建议解决方案只会捕获 JAX-RS 异常,这还不够,尤其是在您使用 DB 和 Hibernate 时。

    ExceptionTrap类的源代码是here

    【讨论】:

    • 我最终还是采用了这个解决方案。虽然 jgm 解决方案有效,但这似乎更“正确”。
    • 这是一种不太像泽西岛的做事方式,但仍然有效。如果您想捕获所有内容,那么您可以为 Exception 创建一个 ExceptionMapper,它会捕获所有内容,并且仍然具有 Reponses 等的所有 Jersey 特性。
    • 这个解决方案为我工作了一段时间,但最后我不得不摆脱它,因为你失去了原来的 HttpRequest 对象。我不知道为什么当时感觉更正确...我已将接受的答案更改为 jgm 的
    猜你喜欢
    • 1970-01-01
    • 2019-08-10
    • 1970-01-01
    • 2022-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多