问题
I recently upgraded a project from 2.1.0 to Grails 2.4.4
In a variety of places we use bindData to map incoming JSON to domain objects including nested objects. This doesn't appear to work after the upgrade or the notation has changed.
For example
Class Book {
Author author
...
}
Passing in JSON
{ "author.id" : 7 }
And calling
def book = new Book()
bindData(book, request.JSON, [include: ['author']])
Would previously find author 7 and attach him to the example book. Now it doesn't bind anything. Has anyone else run into this issue or something similar?
Thanks
Edit:
Updating the incoming JSON fixes this problem and is a potential work around:
{ "author" : { "id" : 7 } }
This format makes more sense but unfortunately it wasn't built this way in the first place.
回答1:
This may help you.
For some reason I cant use the default data binder so I came up with this custom data binder.
Object bindDataCustom (Object targetObject, Map sourceObject) { //named bindDataCustom so it cant confuse with bindData
sourceObject.each{ property, value->
if(property.toString().contains(".")){
String[] nestedProperty = property.toString().split("\\."); //e.g split author.id to author and id
String subObjectName = nestedProperty[0][0].toUpperCase() + nestedProperty[0].substring(1)
String subObjectPropertyName = nestedProperty[1]
Object subObject = Class.forName(packageName + subObjectName, true, Thread.currentThread().getContextClassLoader())."findBy${subObjectPropertyName[0].toUpperCase()}${subObjectPropertyName.substring(1)}"(value)
targetObject."${nestedProperty[0]}" = subObject
}else{
DataBindingUtils.bindObjectToInstance(targetObject, sourceObject, [property], [], null)
}
}
return targetObject;
}
Now you can do like this:
def book = new Book()
bindDataCustom(book, request.JSON)
来源:https://stackoverflow.com/questions/27974665/grails-binddata-doesnt-match-nested-objects-after-upgrade-to-2-4-4