【问题标题】:Grails forms & URL mappingGrails 表单和 URL 映射
【发布时间】:2012-06-24 12:21:25
【问题描述】:

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

所需网址的格式为 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?

谢谢!

【问题讨论】:

    标签: forms grails gsp


    【解决方案1】:
    <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"
    }
    

    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>
    

    【讨论】:

    • 抱歉回复晚了,谢谢!这正是我想要完成的。
    【解决方案2】:

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

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

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

    【讨论】:

    • 真的吗?我不同意您的第一点 - 当您有控制器的明确 url 映射时,它将优先于通用的。 Grails 将在使用更通用的匹配之前尝试识别最佳匹配 - 从技术上讲,通配符较少的映射将优先于通配符较多的映射。阅读本文了解更多详情grails.1312388.n4.nabble.com/…
    • 你的第二点肯定能解决问题。鉴于他有正确的 url 映射
    【解决方案3】:

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

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

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

    def id = params.id
    

    【讨论】:

      【解决方案4】:

      德里克,

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

      1. 请求网址
      2. 参数

      参数使用 urlencode 附加在 url 之后并用 & 分隔,因此,当您的 form 具有 URL http://mydomain.com/controller/action/,并且在这种形式中,您有两个字段:id、name、then、on提交,他们将像这样通过:http://mydomain.com/controller/action/?id=3&name=someName

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多