持久化日期并与JSON嵌套(Persisting date and nested with JSON)

我正在尝试保存嵌套的人,这是json数组并抱怨需要一个Set。

我遇到的另一个问题是,另一个字段日期不能为空,但已包含值。

在将params添加到我的对象之前我需要做什么或者我必须更改我的json? 我正试图像这样保存json帖子:

// relationship of Test //static hasMany = [people: Person, samples: Sample] def jsonParams= JSON.parse(request.JSON.toString()) def testInstance= new Test(jsonParams) //Error requiring a Set [Failed to convert property value of type 'org.codehaus.groovy.grails.web.json.JSONArray' to required type 'java.util.Set' for property 'people'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.Person] for property 'people[0]': no matching editors or conversion strategy found]] //error saying its null Field error in object 'com.Test' on field 'samples[2].dateTime': rejected value [null]; codes [com.Sample] //... "samples[0].dateTime_hour":"0", "samples[0].dateTime_minute":"0", "samples[0].dateTime_day":"1", "samples[0].dateTime_month":"0", "samples[0].dateTime_year":"-1899", "samples[0]":{ "dateTime_minute":"0", "dateTime_day":"1", "dateTime_year":"-1899", "dateTime_hour":"0", "dateTime_month":"0" }, "people":[ "1137", "1141" ], //...

I'm trying to save nested person, which is json array and complains about requiring a Set.

Another problem I encountered, is that another field date cannot be null, but contains value already.

What I need to do before for adding params into my object or I have to change my json is built? I'm trying to save json post like this:

// relationship of Test //static hasMany = [people: Person, samples: Sample] def jsonParams= JSON.parse(request.JSON.toString()) def testInstance= new Test(jsonParams) //Error requiring a Set [Failed to convert property value of type 'org.codehaus.groovy.grails.web.json.JSONArray' to required type 'java.util.Set' for property 'people'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.Person] for property 'people[0]': no matching editors or conversion strategy found]] //error saying its null Field error in object 'com.Test' on field 'samples[2].dateTime': rejected value [null]; codes [com.Sample] //... "samples[0].dateTime_hour":"0", "samples[0].dateTime_minute":"0", "samples[0].dateTime_day":"1", "samples[0].dateTime_month":"0", "samples[0].dateTime_year":"-1899", "samples[0]":{ "dateTime_minute":"0", "dateTime_day":"1", "dateTime_year":"-1899", "dateTime_hour":"0", "dateTime_month":"0" }, "people":[ "1137", "1141" ], //...

最满意答案

首先,这条线是不必要的:

def jsonParams= JSON.parse(request.JSON.toString())

request.JSON可以直接传递给Test构造函数:

def testInstance = new Test(request.JSON)


我不确定你的 Person类是什么样的,但我假设这些数字(1137,1141)是id。 如果是这种情况,那么你的json应该可行 - 有可能直接传递 request.JSON可能有所帮助。 我在本地测试了你的JSON,并且没有关联 hasMany集合的问题。 我也用过:

// JSON numbers rather than strings "people": [1137, 1141] // using Person map with the id "people: [{ "id": 1137 }, { "id": 1141 }]

这两个都运作良好,值得尝试。


关于null dateTime ,我会重写你的JSON。 我会在单个字段中发送 dateTime ,而不是将值拆分为小时/分钟/天/等。 默认格式为 yyyy-MM-dd HH:mm:ss.S和 yyyy-MM-dd'T'hh:mm:ss'Z' ,但这些可以通过 grails.databinding.dateFormats配置设置来定义( config.groovy )。 还有其他方法可以进行绑定( @BindingFormat注释),但最简单的方法就是以grails无需额外配置即可处理的方式发送日期。

如果您将dateTime拆分为碎片,那么您可以使用@BindUsing批注:

class Sample{ @BindUsing({obj, source -> def hour = source['dateTime_hour'] def minute = source['dateTime_minute'] ... // set obj.dateTime based on these pieces }) Date dateTime }


您对JSON的另一个评论是,您似乎已将 samples[0]定义了两次,并且正在为内部集合使用2种语法(JSON数组和索引键)。 我个人会坚持用一种语法来清理它:

"samples": [ {"dateTime": "1988-01-01..."} {"dateTime": "2015-10-21..."} ],"people": [ {"id": "1137"}, {"id": "1141"} ],

First off, ths line is unnecessary:

def jsonParams= JSON.parse(request.JSON.toString())

The request.JSON can be directly passed to the Test constructor:

def testInstance = new Test(request.JSON)


I'm not sure what your Person class looks like, but I'm assuming those numbers (1137, 1141) are ids. If that is the case, then your json should work - there's a chance that passing the request.JSON directly could help. I tested your JSON locally and it has no problem associating the hasMany collection. I also used:

// JSON numbers rather than strings "people": [1137, 1141] // using Person map with the id "people: [{ "id": 1137 }, { "id": 1141 }]

Both of these worked as well and are worth trying.


Concerning the null dateTime, I would rework your JSON. I would send the dateTime in a single field, instead of splitting the value into hour/minute/day/etc. The default formats are yyyy-MM-dd HH:mm:ss.S and yyyy-MM-dd'T'hh:mm:ss'Z', but these can be defined by the grails.databinding.dateFormats config setting ( config.groovy). There are other ways to do the binding as well ( @BindingFormat annotation) but it's going to be easiest to just send the date in a way that grails can handle without additional configuration.

If you are dead set on splitting the dateTime into pieces, then you could use the @BindUsing annotation:

class Sample{ @BindUsing({obj, source -> def hour = source['dateTime_hour'] def minute = source['dateTime_minute'] ... // set obj.dateTime based on these pieces }) Date dateTime }


An additional comment on your JSON, you seem to have samples[0] defined twice and are using 2 syntaxes for your internal collections (JSON arrays and indexed keys). I personally would stick with a single syntax to clean it up:

"samples": [ {"dateTime": "1988-01-01..."} {"dateTime": "2015-10-21..."} ],"people": [ {"id": "1137"}, {"id": "1141"} ],

更多推荐