如何在 grails 控制器中使用路径变量?

Posted

技术标签:

【中文标题】如何在 grails 控制器中使用路径变量?【英文标题】:How can I use path variables in grails controller? 【发布时间】:2014-08-23 04:20:02 【问题描述】:

我一直在尝试在 grails 控制器中使用路径变量,但我无法实现。 背后的目的是验证提交到我需要强制执行的 url 的参数。我无法通过 RequestParam 实现它,所以我切换到 PathVariable 以便提交的没有所需参数的 url 应该被 grails 控制器本身过滤掉,而不是我添加 if/else 检查有效性。

所以,我可以说明如下: 我的网址如下:-

'<appcontext>/<controller>/<action>?<paramName>=<something>'

现在,要强制“paramName”,我在 Grails 中找不到任何方法(Spring MVC 提供了 @RequestParam 注释,可以让我将“required”设为 true)。

我认为的另一种选择是使用路径变量,以便可以将“paramName”包含在 URL 本身中。所以我尝试如下:

'<appcontext>/<controller>/<action>/$paramName'

为了验证上面的 URL,我编写了特定的映射,但有些映射也不起作用..

以下是我写的具体映射:-

"/<controllerName>/<action>/$paramName" 
            controller:<controller to take request>
            action:<action to do task>
            constraints 
                paramName(nullable: false,empty:false, blank: false)
            
        

我尝试在控制器中使用 @PathVariable 和 @RequestParam 之类的弹簧注释,如下所示:-

 def action(@PathVariable("paramName") String param)
        //code goes here
    

【问题讨论】:

“它怎么也行不通”——到底出了什么问题?请记住,约束只是决定这个特定的 URL 映射是否可以应用于某个请求。如果您有其他可以匹配相同 URL 的映射(例如通用 "$controller/$action?/$id?" 映射),那么可能是您的约束实际上工作正常,拒绝该特定映射,但是通过不同的映射调用同一个控制器. nullable: false, empty: false, blank: false 约束参数实际上并没有做任何事情。由于映射不包括?,因此必须存在参数才能应用此映射。您可以消除这些限制。 【参考方案1】:

如果您将方法参数命名为与请求参数重命名相同,Grails 会为您处理...

// In UrlMappings.groovy
"/foo/$someVariable/$someOtherVariable" 
    controller = 'demo'
    action = 'magic'

然后在你的控制器中:

// grails-app/controllers/com/demo/DemoController.groovy
class DemoController 
    def magic(String someOtherVariable, String someVariable) 
        // a request to /foo/jeff/brown will result in
        // this action being invoked, someOtherVariable will be
        // "brown" and someVariable will be "jeff"
    

希望对你有帮助。

编辑:

另一种选择...

如果由于某种原因您希望方法参数有不同的名称,您可以像这样显式地将方法参数映射到请求参数...

import grails.web.RequestParameter
class DemoController 
    def magic(@RequestParameter('someVariable') String s1, 
              @RequestParameter('someOtherVariable') String s2) 
        // a request to /foo/jeff/brown will result in
        // this action being invoked, s2 will be
        // "brown" and s1 will be "jeff"
    

【讨论】:

它起作用了,但是我觉得它有点黑客,因为我想要一个如果约束失败,请求不应该通过的行为。但是在这里,就像如果它匹配控制器中具有相同名称的操作,那么请求将通过。如何在不更改默认操作名称的情况下强制请求不执行其他操作(URL 映射除外)? 我不明白你的问题。除非请求与 UrlMappings 中定义的相应映射匹配,否则任何请求都不会进入控制器中的操作。例如,如果您消除了 /$controller/$action?/$id? 映射并且您只有我上面定义的 URL 映射,则对 /foo/jeff/brown 的请求将起作用,但 /demo/magic/ 将不起作用。 /demo/magic?someVariable=jeff&amp;someOtherVariable=brown/demo/magic/jeff/brown 等也不会。“通过”的唯一请求是匹配 URL 映射的请求。

以上是关于如何在 grails 控制器中使用路径变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 grails 中使用会话

在 Grails 控制台中导入服务?

从 Grails 中的过滤器定义控制器可访问变量

Grails:在用户会话期间存储数据的最佳方法[关闭]

我如何在 grails 2.3.1 中使用控制器来休息 api?

如何在 Grails 中实现超时页面