2012-06-22 110 views
1

我正在编写一个Grails应用程序,我希望设置一个允许用户输入图像ID号的表单,并将此值传递给从S3中检索图像的控制器/操作对于给定的图像ID。Grails表单和URL映射

所需的url格式为example.com/results/1234。我已经安装了下列URL映射:

class UrlMappings { 

    static mappings = { 
     "/$controller/$action?/$id?"{ 
      constraints { 
       // apply constraints here 
      } 
     } 

     "/results/$id?" { 
      controller = "s3Image" 
      action = "getS3Image" 
     } 

     "/"(view:"/index") 
     "500"(view:'/error') 
    } 
} 

以下是我怎么也安装形式:

<g:form controller="results" method="get"> 
    <input type="text" name="id" class="input-xxlarge" placeholder="http://www.example.com"> 
     <button class="btn btn-inverse">Submit</button> 
</g:form> 

然而,这似乎形式提交给example.com/results?id=12345。

我该如何改变我的表单或映射,以便在表单提交后生成所需的url?

谢谢!

回答

3
<g:form controller="results" method="get"> 

将生成一个HTML表单,其操作URL为/results(控制器命名为“results”的反向URL映射,不含操作或ID)。当提交此表单时,浏览器将在此URL的末尾添加?id=1234,因为表单方法为GET。这不是您可以在服务器端的URL映射中影响的东西。

相反,您应该将表单POST发送到重定向到getS3Image操作的其他控制器操作。重定向可以访问服务器端的ID,因此可以为重定向生成友好的URL。

UrlMappings:

"/results/$id?" { 
    controller = "s3Image" 
    action = "getS3Image" 
} 

"/findImage" { 
    controller = "s3Image" 
    action = "find" 
} 

S3ImageController:

def find() { 
    redirect(action:"getS3Image", id:params.id) 
} 

def getS3Image() { 
    // as before 
} 

GSP:

<g:form controller="s3Image" action="find" method="post"> 
    <input type="text" name="id" class="input-xxlarge" placeholder="http://www.example.com"> 
     <button class="btn btn-inverse">Submit</button> 
</g:form> 
+0

对不起,迟到的回应,但谢谢!这正是我想要完成的。 –

0

我想你在这里有两个问题。首先,UrlMappings规则按照外观顺序从上到下进行匹配。 Grails匹配的第一条规则是 "/$controller/$action?/$id?"。移动上面的规则 "/results/$id?",它应该优先。 - 查看以下评论​​帖子

你的第二个错误是声明的形式。我想你的意思是:

<g:form controller="s3Image" method="getS3Image"> 
+1

真的吗?我不同意你的第一点 - 当你有一个控制器的显式url映射时,它将优先于广义映射。 Grails会在使用更通用的匹配之前尝试识别最佳匹配 - 技术上来说,具有较少通配符的映射将优先于具有较多通配符的映射。阅读更多细节http://grails.1312388.n4.nabble.com/URL-Mapping-question-td3556768.html#a3565451 –

+0

你说得对@sudhir。 –

+0

你的第二点应该明确地解决问题。鉴于他有正确的网址映射 –

1

德里克,

你看到的是正确的行为。对于GET请求你的要求

  • 参数两件事情

    1. URL

    参数使用进行urlencode的URL后追加和&分开的,所以,当你有形式与URL http://mydomain.com/controller/action/ ,在这种形式下,你有两个字段:id,name,然后,在提交后,他们将像这样传递:http://mydomain.com/controller/action/?id=3&name=someName

    URLMappings are mappin只有它的URL部分。因此,在您的示例中,UrlMapping仅匹配/ results /,并且不传递id。

    但这不要紧,因为你仍然可以访问你的控制器中的id参数,只是做这样的(s3Image控制器内):

    def getS3Image() { 
        def id = params.id 
    } 
    
  • 0

    尝试在urlMapping中很简单的变化:

    "/results/$id?" { 
        controller = "s3Image" 
        action = "getS3Image" 
        id = $id 
    } 
    

    ,然后确保您通过在s3Image控制器访问的ID:

    def id = params.id