【问题标题】:Request params not getting bound to grails command object请求参数未绑定到 grails 命令对象
【发布时间】:2012-11-20 16:33:55
【问题描述】:

我已经从 Grails 1.3.6 升级到使用 Grails 2.1.1,并且一些正在工作的命令对象不再从请求参数中获取数据绑定。

我创建了一个实验控制器来重现问题:

package my.controllers

import troubleshooting.*

class ExperimentalController {


    def toggle(ExperimentalCommand cmd){
        render "<pre>${this.properties}</pre>"
        render "<h3>Raw</h3>The cmd.id was/is '${cmd.id}'<br/>The params.id was/is '${params.id}'<br/>They should be the same but they aren't<br/>The target ala cmd then params was/is '${cmd.target}' '${params.target}'<br/><hr/><hr/>"
        bindData(cmd,params)//not even this works wtf?
        render "<h3>bindData(cmd,params)</h3>The cmd.id was/is '${cmd.id}'<br/>The params.id was/is '${params.id}'<br/>They should be the same but they aren't<br/>The target ala cmd then params was/is '${cmd.target}' '${params.target}'<br/><hr/><hr/>"
        cmd = new ExperimentalCommand()
        render "<h3>New Cmd</h3>The cmd.id was/is '${cmd.id}'<br/>The params.id was/is '${params.id}'<br/>They should be the same but they aren't<br/>The target ala cmd then params was/is '${cmd.target}' '${params.target}'<br/><hr/><hr/>"
        cmd = new ExperimentalCommand(params)
        render "<h3>New Cmd binding constructor</h3>The cmd.id was/is '${cmd.id}'<br/>The params.id was/is '${params.id}'<br/>They should be the same but they aren't<br/>The target ala cmd then params was/is '${cmd.target}' '${params.target}'<br/><hr/><hr/>"
        bindData(cmd,params,[include:["id","target"]])
        render "The cmd.id was/is '${cmd.id}'<br/>The params.id was/is '${params.id}'<br/>They should be the same but they aren't<br/>The target ala cmd then params was/is '${cmd.target}' '${params.target}'<br/><hr/><hr/>"

    }
}
class ExperimentalCommand{
    def id,target,action,controller

}

如果你执行:

grails 运行应用程序

然后转到:

http://localhost:8080/YourApp/experimental/toggle/foo?target=bullseye&cmd.target=whatever

你会看到(在我的情况下)第一次尝试渲染 cmd.id 显示它为 null,尽管 params.id 是 foo

从这个练习中,我还发现未指定包含 id 和目标的 bindData 调用完全失败,并且使用参数显式实例化命令对象会导致异常。

我在这里完全不知所措。我已经尝试过诸如重写 getInstanceControllersApi 方法以返回一个记录不同 bindData 调用的包装器,这样我就可以看到发生了什么以及如何控制它,但什么也没告诉我。

我可以将控制器和操作字段添加到命令对象,以防止它在我调用 new ExperimentalCommand(params) 时出错,但我不应该做任何 Grails 文档声明绑定将完成的事情调用动作之前的命令对象的实例,但在我的情况下它不是。

谷歌没有发现任何东西,所以显然我是第一个不得不处理这个问题的人。

问题是如何解决这个问题?

【问题讨论】:

    标签: grails grails-controller grails-2.1


    【解决方案1】:

    1.3.6 和 2.x 之间的数据绑定机制发生了各种变化,我会尝试的第一件事是为命令对象属性提供适当的类型,而不仅仅是def

    class ExperimentalCommand{
        String id
        String target
        String action
        String controller
    }
    

    The Grails 2.1.1 docs 用于数据绑定谈谈new CommandObject(params) 和obj.properties = params 的数据绑定形式并声明

    Grails 中的这些数据绑定形式非常方便,但也是不分青红皂白的。换句话说,它们将绑定目标对象的所有非瞬态、typed [my bold] 实例属性,包括您可能不想绑定的那些。

    【讨论】:

    • 我也试过这些东西。根据文档严格输入是必需的,因此它可以进行转换,但即使这样仍然会在命令对象中出现空值
    • 我刚刚调整了日志记录设置以在调试级别记录 grails 内部和 spring 类,我发现:code
      DEBUG validation.DataBinder - Field [target] 已从PropertyValues 并且不会被绑定,因为在允许字段列表中没有找到它 2012-11-20 12:43:32,469 [http-bio-443-exec-3] DEBUG validation.DataBinder - Field [id] has已从 PropertyValues 中删除,不会被绑定,因为在允许字段列表中没有找到它 2012-11-20 12:43:32,469 [http-bio-443-exec-3]
      code
    • 你改成String了吗?出于安全考虑,id 不会被绑定,你必须手动绑定它,但我认为所有其他的都是允许的。
    • 我刚刚通过添加: bindable: true to the constraints 我仍然认为有些事情发生了——这使得代码不那么枯燥和时髦;我现在正在我的 Config.groovy 或 BuildConfig.groovy 中搜索可能已指示它使用此行为的设置
    猜你喜欢
    • 2014-09-07
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多