【问题标题】:Can annotations be used to keep Groovy/Grails code DRY?可以使用注释来保持 Groovy/Grails 代码干燥吗?
【发布时间】:2013-04-02 03:06:31
【问题描述】:

我正在使用 Grails 2.2.0 来建立一个网站,我正在寻找关于保持我的代码 DRY 的最佳实践/建议。这是我第一次使用 Grails,我对 Groovy 和 Grails 都有一定的了解,但无论如何我都不是专家。我确实来自 Java+Spring 背景。

我有虚 URL 作为要求。本质上,URI 被用作查找所需模型的键。如果找不到,请重定向到主页。如果确实存在,它将在控制器操作的帮助程序中使用(由闭包指示,仅在存在时执行)。这是我当前(工作)来源的经过消毒的示例:

UrlMappings.groovy:

"/$groupName/dashboard"(controller: "dashboard", action: "viewAll")
"/$groupName/dashboard/create"(controller: "dashboard", action: "createRecord")
"/$groupName/foo/$action?"(controller: "foo")

BaseController.groovy:

Group requireGroupFromUrl(Closure c) {
  if (params.groupName == null) {
    redirect(controller: "home", action: "index")
    return
  }
  else {
    Group group = Group.findByUrlName(params.groupName)
    if (group == null) {
      redirect(controller: "home", action: "index")
      return
    }

    c.call(group)
  }
}

DashboardController.groovy 扩展了 BaseController:

def viewAll() {
  requireGroupFromUrl({ Group group -> gymHelper(group)})
}

def viewAllHelper(Group group) {

  // some logic involving 'group'

  def map = [groupInstance: group, /* OTHER CALCULATED/QUERIED PARAMS*/ ]
  render(view: "/groupView", model: map)
}

这行得通。然而,对于辅助方法的需求似乎很笨拙。

乍一看,过滤器似乎可以完成这项工作,但我需要指定要从过滤器中排除哪些路径(/、/login、/register 等),这似乎使其保持紧密耦合到 UrlMappings 中的条目。或者我可以以某种方式将uri 与多种模式一起使用?例如uri: '*/dashboard/**, */foo/**'?如何将检索到的对象向前传递?

是否可以通过使用仅注释适用控制器操作的 Around 建议的注释来更好地实现这一点?如果是这样,Aspect 可以调用redirect 吗?如何将检索到的对象传递给带注释的控制器操作?即

@GroupRequired
def viewAll() {
  ...
}

【问题讨论】:

  • 昨晚我意识到,在开始尝试过滤器时,uri 模式会很困难,因为/$groupName 是我的应用程序中的有效路径。

标签: grails groovy controller annotations dry


【解决方案1】:

控制器beforeInterceptor 可以干净利落地完成此任务:

abstract class BaseController {
    def beforeInterceptor = {
        if (params.groupName == null) {
            redirect(controller: "home", action: "index")
            return false
        }

        Group group = Group.findByUrlName(params.groupName)
        if (group == null) {
            redirect(controller: "home", action: "index")
            return false
        }

        // put the group into the params object
        // for use in the controllers
        params.group = group
    }
}

class ChildController extends BaseController {
    def myAction() {
        Group g = params.group

        // do things
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2021-06-17
    • 1970-01-01
    • 2011-08-18
    • 2019-01-26
    • 2011-04-24
    相关资源
    最近更新 更多