简化Grails控制器中的实体查找(典型的get / findById)

时间:2009-11-18 09:51:59

标签: grails error-handling

几乎每个控制器操作都会根据某些用户输入查找一个或多个实体。有一段时间我一直想要删除一些这些枯燥乏味的样板代码:

def show = {
   def entity = null
   if (params.id && params.id.isLong() && params.id.toLong() >= 0) 
      entity = Book.get(params.id.toLong())

   if (!entity) {
      flash.message = "Could not find, blah blah blah"
      return redirect(...)
   }

   // Useful code
}

我目前的方法是将findEntry方法注入所有控制器。

void injectFindEntryMethod() {
   grailsApplication.controllerClasses.each { def c ->
      c.metaClass.findDomainEntry = { def domainClass, def entryId ->
         def entry = null
         if (entryId && entryId.isLong() && entryId.toLong() >= 0)
            entry = domainClass.findById(entryId)

         if (!entry)
            throw new DomainInstanceNotFoundException(domainClass, entryId)

         return entry
      }
   }
}

此方法背后的基本思想是,当无法找到条目时,它将抛出异常。目前,我正在使用Grails 1.1中的“声明性错误处理”功能“捕获”此异常。

"500"(controller: "error", action: 'domainInstanceNotFound', exception: DomainInstanceNotFoundException)

这个解决方案的巧妙之处在于show动作中的膨胀代码被简化为:

def show = {
   def entry = findDomainEntry(BlogEntry, params.id)

   // Useful code
}

不幸的是,这也有一些缺点,但是,嘿,这就是为什么我们有Stackoverflow的权利? : - )

问题/缺点:

  1. 这将导致记录异常的堆栈跟踪,这很烦人,因为我在我的ErrorController中处理异常。
  2. 我无法访问action方法中的异常对象,但是视图中的$ {exception}可以访问该对象(我无法理解为什么它以这种方式实现)。
  3. 你们怎么看待这种方法?有什么方法可以改善吗?对于我上面提到的缺点的任何建议或灵魂?如果我的问题的范围太大,我很抱歉将它分成多个问题是没有意义的。

0 个答案:

没有答案