【问题标题】:How to nest Grails controller paths如何嵌套 Grails 控制器路径
【发布时间】:2013-12-10 13:40:57
【问题描述】:

我知道可以这样做:

带有操作栏的控制器 foo 可以通过 (1) 访问:

/appname/foo/bar

它可以使用 URL 映射重写 - 例如:

"/foobar/foo/$action"(controller: "foo")

然后通过(2)访问它:

/appname/foobar/foo/bar

但仍然可以通过 (1) 访问它。这当然是因为默认的 URL 映射:

"/$controller/$action?/$id?"()

但我宁愿不删除它,因为这基本上意味着我必须手动将映射写入遵循默认模式的每个其他控制器/动作。

是否可以在不使用 URL 映射的情况下获取特定控制器/操作(如 (2))的 url 模式?如果没有,是否有一种简单的方法可以从默认映射闭包中“排除”控制器?

【问题讨论】:

  • 我想我明白你在追求什么,蹄子。我认为您无法按照自己的意愿准确地实现它。默认的 /$controller/$action/$id 映射必须变为 //$action/$id where = "foo"。脖子有点痛,但实际上我必须做类似的事情。您的另一种选择是保留默认的 Grails 规则,并在需要打破该规则的所有内容前面加上路径中的某些内容。
  • 好吧。后一个建议-“您的另一个选择是保留默认的 Grails 规则,并在需要破坏该规则的所有内容前面加上路径中的某些内容”-您将如何做到这一点?我想保留默认的 URL 映射,但为某些只能在前缀内访问的控制器打破它......例如foo 控制器只能通过 foobar/foo 访问 :)
  • 我将用一些示例代码发布答案。我不完全理解你的要求,但我会告诉你我的意思。

标签: grails url-mapping


【解决方案1】:

解决方案是更改默认映射,以排除希望的特殊控制器 URL。

class UrlMappings {

  static myExcludes = ["foo"]

  static mappings = {
    "/foobar/foo/$action"(controller: "foo") // your special Mapping

    // the rewritten default mapping rule
    "/$aController/$aAction?/$id?"{ 
        controller = { (params.aController in UrlMappings.myExcludes) ? "error" : params.aController }
        action = { (params.aController in UrlMappings.myExcludes) ? "notFound" : params.aAction }
        constraints {
            // apply constraints here
        } 
     }
  }
}

对于重写的默认规则,您必须防止使用默认变量名称 $controller 和 $action。除了 error/notFound,您还可以重定向到其他位置。

【讨论】:

    【解决方案2】:

    如果你可以让你的规则破坏场景比 Grails 默认的 $controller/$action?$id?模式,那么默认值可以保持原样,并将应用于异常模式之外的所有内容。我创建了一个快速的 Person 域并执行了 generate-all。然后我自己做了一个 BreakRuleController。

    class UrlMappings {
    
    static mappings = {
    
        "/b/$action?/$someVariable?"(controller: "breakRule")
    
        "/$controller/$action?/$id?(.${format})?"{
            constraints {
                // apply constraints here
            }
        }
    
        "/"(view:"/index")
        "500"(view:'/error')  
       }
    

    }

    使用此 UrlMapping,如果您访问 URI“/b/foo/stackoverflow”,它将打印“Breaking Rules foo: stackoverflow”。如果你转到“/b”,它会打印“Breaking Rules index”。

    然后,如果您使用标准的 Person URI,所有默认 Grails 脚手架也可以正常工作(创建、编辑等),因为它会映射到典型的“$controller/$action?/$id?”模式。

    类 BreakRuleController {

       def index() {
           print "Breaking Rules index"
       }
    
       def foo(String someVariable) {
           print "Breaking Rules foo: " + someVariable
       } 
    

    }

    【讨论】:

    • 但我仍然可以转到“/breakRule/**” - 我不能吗?就我所见,上面的例子和我的例子(2)一模一样?
    • 您能澄清一下您的问题吗?我不完全了解您要实现的目标。我想我对 foo, bar, foobar 有点迷失了。
    • 在您自己的示例中,由于特定的 URL 映射,可能会到达“/b/foo/stackoverflow”。然而!仍然可以直接转到“/breakRule/foo/stackoverflow”。后者是因为默认映射。我不想避免后者,而不必手动编写所有其他 URL 映射 - 也就是说,删除默认的常规动态 URL 映射。明白了吗?
    猜你喜欢
    • 2018-04-05
    • 2019-12-12
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多