gpt4 book ai didi

grails - 如何在 Grails REST Controller 中捕获异常

转载 作者:行者123 更新时间:2023-12-01 15:20:22 28 4
gpt4 key购买 nike

如果您使用 Controller 来实现 rest API,您希望处理任何抛出的异常并返回通用或特定的格式良好的 REST 响应。

我们不能使用全局错误 URL 映射方法,因为应用程序有许多 API 和接口(interface),具有不同的响应要求,我们也不知道会抛出哪种类型的 Grails HTTP 错误代码(例如不要不知道它是否会是 400、422、500 等)。此外,如果我们使用错误页面映射,我们将无法将相关数据放入 JSON 响应中。

例如这将生成一个 GrailsRuntimeException:

class SomeController {
def payload = request.JSON
def someMethod() {
BigDecimal x = new BigDecimal(payload.notExists)
}

问题是,似乎不可能捕捉到任何抛出的错误。

例如这种方法都不是:

def handleRuntimeException(RuntimeException e) {
render("some JSON error message")
}

也不是这种方法:

try {
:
}
catch (GrailsRuntimeException e) {
render("some JSON error message")
}

有效 - 它永远不会捕获错误。

尝试过 GroovyRuntimeException、Exception、MissingMethodException、Throwable 等

我们能想到的唯一解决方案是不在 Controller 中做任何工作,在服务中做所有事情,显然我们可以捕获错误。

这种方法:

static mappings = {
"500"(controller: "error")
}

出于以下几个原因我们不需要:

  1. 我们在不同的 Controller 中有多个不同的 API,它们需要不同的响应格式。
  2. 我们还有 UI Controller ,它需要显示堆栈跟踪等的默认错误系统。
  3. 我们想在发生异常的 Controller 中处理错误,这样我们就可以清理,或者至少可以记录或返回只有 Controller 知道的统计信息。

已决定唯一的方法是将所有代码移动到服务中,除了传递请求和呈现结果字符串外,在 Controller 中什么都不做。即所有参数处理,尤其是数字转换,都在服务中完成。

最佳答案

具有讽刺意味的是,您认为不理想的解决方案正是您应该始终采用的解决方案。这不是 PHP - 不要将逻辑放在 Controller (或 GSP)中。

默认情况下,服务是事务性的,因此它们是放置写入数据库的代码的好地方,因为这应该总是发生在事务中。它们对于业务逻辑也非常出色,无论它是事务性的还是非事务性的,您可以使用 @Transactional 注释各个方法以将方法划分为在事务中运行的方法和不在事务中运行的方法,或者将服务分成一些完全事务性的服务和一些不完全事务性的服务。

如果您将所有与 HTTP 相关的代码保留在 Controller 中,从 params 进行数据绑定(bind),并调用辅助类(服务、域类、标签库等),您会得到一个很好的关注点分离,如果服务层对 paramsHttpServletRequest、HTTP session 等一无所知,那么它很容易在其他 Grails 应用程序中重用,甚至在非-Grails 应用程序。它们也将更容易测试,因为没有那么多相互关联的代码需要模拟或以其他方式使测试友好。

使用这种方法, Controller 基本上变成了哑路由器,接受请求,调用助手来完成真正的工作,并委派页面呈现或响应写入,或者重定向或转发。

关于grails - 如何在 Grails REST Controller 中捕获异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27983519/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com