我正在编写一个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?
谢谢!
<g:form controller="results" method="get">
将生成一个 HTML 表单,其操作 URL /results
(名为"results"的控制器的反向 URL 映射,没有操作或 ID)。 提交此表单时,浏览器将在此 URL 的末尾添加?id=1234
,因为表单方法是 GET。 这不是您可以在服务器端的 URL 映射中影响的内容。
相反,您应该将表单 POST 发送到重定向到getS3Image
操作的其他控制器操作。 重定向将有权访问服务器端的 ID,因此可以为重定向生成外观友好的 URL。
网址映射:
"/results/$id?" {
controller = "s3Image"
action = "getS3Image"
}
"/findImage" {
controller = "s3Image"
action = "find"
}
S3图像控制器:
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>
Derek,
你所看到的是正确的行为。对于 GET 请求,您有两件事
- 请求网址
- 参数
参数使用 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
}
UrlMap 中进行非常简单的更改:
"/results/$id?" {
controller = "s3Image"
action = "getS3Image"
id = $id
}
然后确保您在 s3Image 控制器中可通过以下方式访问 ID:
def id = params.id
我认为你在这里有两个问题。首先,UrlMappings 规则按出现顺序(从上到下)进行匹配。圣杯匹配的第一条规则是- 检查帖子下面的评论。"/$controller/$action?/$id?"
。将您的规则移到上面"/results/$id?"
,它应该优先。
你的第二个错误是形式声明。我想你的意思是:
<g:form controller="s3Image" method="getS3Image">