1

我正在编写一个 Grails 应用程序,我想在其中设置一个允许用户输入图像 ID 号的表单,该值将传递给从 S3 检索给定图像 ID 的图像的控制器/操作。

所需的 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?

谢谢!

4

4 回答 4

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

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

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

网址映射:

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

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

S3ImageController:

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

def getS3Image() {
    // as before
}

普惠制:

<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>
于 2012-06-23T10:07:32.513 回答
1

德里克,

你所看到的是正确的行为。对于 GET 请求,您有两件事

  1. 请求网址
  2. 参数

使用 urlencode 将参数附加在 url 之后并用 & 分隔,因此,当您具有URL http://mydomain.com/controller/action/的表单时,在此表单中您有两个字段:id、name,然后,在提交时,它们将像这样传递: http://mydomain.com/controller/action/?id=3&name= someName

URLMappings 仅映射其中的 URL 部分。因此,在您的示例中, UrlMapping 仅与 /results/ 匹配,并且未传递 id 。

但这没关系,因为您仍然可以访问控制器中的 id 参数,只需这样做(在 s3Image 控制器中):

def getS3Image() {
     def id = params.id
}
于 2012-06-22T08:33:51.410 回答
0

在 UrlMapping 中尝试非常简单的更改:

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

然后确保您可以通过以下方式在 s3Image 控制器中访问 id:

def id = params.id
于 2012-06-22T09:06:48.833 回答
0

我认为你在这里有两个问题。首先,UrlMappings 规则按照出现的顺序从上到下进行匹配。grails 匹配的第一条规则是"/$controller/$action?/$id?". 将您的规则移到"/results/$id?"上面,它应该优先。-检查帖子下方的评论

您的第二个错误是表格声明。我想你的意思是:

<g:form controller="s3Image" method="getS3Image">
于 2012-06-22T07:59:40.627 回答