Grails 命令对象:如何将 request.JSON 加载到其中?

Posted

技术标签:

【中文标题】Grails 命令对象:如何将 request.JSON 加载到其中?【英文标题】:Grails Command Object: How to load request.JSON into it? 【发布时间】: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 "ProfileCommandid=$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: ProfileCommandid=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() 工作。谢谢,伊恩!

【问题讨论】:

【参考方案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

【讨论】:

以上是关于Grails 命令对象:如何将 request.JSON 加载到其中?的主要内容,如果未能解决你的问题,请参考以下文章

Grails:如何使用命令对象验证由项目列表组成的 POST 正文?

在 grails 控制器中模拟命令对象导致 hasErrors() 无论如何都返回 false !请帮忙

Grails 命令对象自定义验证消息代码

Grails:嵌套的命令对象

Grails:普通类和命令对象之间的区别?

grails验证嵌套命令对象不起作用