【发布时间】:2015-11-13 19:18:53
【问题描述】:
我正在使用 Grails 2.3.11。
当我要去localhost:8080/myapp/questionnaire/show/3 时,应用程序显示一个空白页。并且调试甚至不会进入以下任何方法。
class QuestionnaireController {
def beforeInterceptor = [action: this.&loadQuestionnaire, only: ['show']]
Questionnaire questionnaireInstance
def show = {
render(view: 'show', model: [questionnaire: questionnaireInstance])
}
private def loadQuestionnaire() {
questionnaireInstance = Questionnaire.findById(params.id)
if(!questionnaireInstance) {
redirectWhenNotFound(params.id)
}
}
private def redirectWhenNotFound(def id) {
flash.message = message(code: 'default.not.found.message', args: [
message(code: 'questionnaire.label'),
id
])
redirect(uri: "/")
}
但是,当我尝试localhost:8080/myapp/questionnaire/show 时,它转到loadQuestionnaire(),显然找不到域实例,因为params.id 不存在,所以它转到redirectWhenNotFound() 并正确重定向到主页.
问题是 - 为什么它不能正常工作?
编辑:
只有当有给定 id 的实例存在时才会显示空白页,如果没有,则进入方法。
最终我找到了解决方案,在下面的答案中。
【问题讨论】:
-
你试过不带
beforeInterceptor和不带questionnaireInstance吗?看起来这可以通过更简单的方式完成,并且在控制器中保留实例变量通常不是一个好主意。 -
@tylerwal 这个项目有一个非常相似的例子,不同的是在同一个控制器中重定向
action,而不是uri。如果你说声明这不是一个好主意,最好证明这种观点是正确的。这可能不是最好的想法,但它允许简化代码并且不在许多方法中重复相同的步骤。干燥。 -
我最初的评论是关于认为控制器将是单例范围的并且存在并发问题的风险,但是在调查之后它们实际上是请求范围的并且问题不是那么大。我还是觉得这段代码不用拦截器可以精简写成更简单的方式。
-
您知道这不是控制器中的唯一操作吗?您正在制作完全偏离主题的 cmets,即使它们是“主题”,您也没有提供任何 更好 解决方案(到底是什么?)......对不起,但我不能看到重点。恕我直言,如果您无法提供有用的信息或任何实际建议,最好删除这些 cmets。
-
我不是想冒犯你——评论的重点是
ask for more information or suggest improvements。对于您的控制器为何呈现空白页面的问题,我没有提出答案,因此我没有发布答案,但我建议进行改进。似乎Questionnaire的获取将作为一个动作参数得到改进,而不是在拦截器中:def show(@RequestParameter('id')Questionnaire questionnaireInstance ) = {,然后在必要时在动作中重定向。
标签: grails