【问题标题】:Grails Command Object: How to load request.JSON into it?Grails 命令对象:如何将 request.JSON 加载到其中?
【发布时间】:2012-06-05 18:12:40
【问题描述】:

问题:有没有办法自动绑定 request.JSON 数据的命令对象?

鉴于我的 grails 控制器中的这个简单的 Command 对象:

class ProfileCommand{

int id
String companyName

static constraints = {
    companyName blank: false
    id nullable: false
}

@Override
public String toString() {
    return "ProfileCommand{id=$id, companyName='$companyName'}";
}
}

和我的控制器方法签名:

def update(ProfileCommand command) {...}

如何将request.JSON 数据放入我的命令对象?

到目前为止,我能够做到的唯一方法是在 update() 方法中手动创建命令对象,将 request.JSON 作为构造函数参数传递:

    def command = new ProfileCommand(request.JSON)

    log.debug "Command object contents: $command"

上面的调试命令产生:

Command object contents: ProfileCommand{id=1, companyName='Blub Muckers'}

这正是我想要的(向 Oliver Tynes 大声疾呼上述解决方案)。不幸的是,在我创建命令后调用command.validate() 会产生以下异常:

Class org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException
Message Tag [validate] is missing required attribute [form]

我使用的是 v2.0.3,uris 产生了与 v2.0.4 相同的异常。

更新 根据 grails 邮件列表上的 Ian Roberts,您需要将 @Validateable 注释添加到命令类以使 validate() 工作。谢谢,伊恩!

【问题讨论】:

    标签: grails grails-controller


    【解决方案1】:

    我不确定是否有任何配置方式可以进行自动 JSON 参数数据绑定;您可能可以做的一件事是为您的操作编写一个过滤器,该过滤器接受 JSON 请求输入,基本上将 request.JSON 直接重新映射到根参数映射,理论上这应该允许自动数据绑定发生。

    类似:

    class JSONParamMapFilters {
      def filters = {
         before = {
            remapFilter(controller:'yourController', action:'update') {
               request.JSON.each { k,v ->
                   params[k] = v
               }
            }
         }
      }
    }
    

    然后您可以通过正则表达式/命名约定将此过滤器扩展到任何适用的控制器操作。

    【讨论】:

    • 这行得通。除非其他人有其他建议,否则我会将其标记为答案。谢谢,Aquatoad!
    • 很高兴为您提供帮助。我也会删除由@Validateable 注释修复的位。
    【解决方案2】:

    您应该在UrlMappings.groovy 中使用parseRequest=true。例如:

    "/user/$id/$action?"(controller: "userProfile", parseRequest: true) {
        constraints {
            id matches: /^[0-9]+$/
        }
    }
    

    然后您可以使用params 变量或将json绑定到方法参数中的命令对象:

    def index(MyCommand command){...}

    两者都应该工作。但在某些情况下,它会丢失一些来自 json 的信息(绑定到地图)。

    【讨论】:

    • 仅供 grails 2.3 上的读者参考,parseRequest 现在什么都不做,您需要手动处理 JSON。
    【解决方案3】:

    如果您不使用命令对象作为任何控制器操作的参数,那么 Grails 不会使用 validate 方法自动增强它。您需要使用 @Validateable 注释该类以告诉 Grails 它应该被增强。

    http://grails.org/doc/latest/guide/validation.html#validationNonDomainAndCommandObjectClasses

    【讨论】:

      猜你喜欢
      • 2015-10-15
      • 1970-01-01
      • 2018-11-06
      • 2013-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-24
      • 1970-01-01
      相关资源
      最近更新 更多