|
This post has NOT been accepted by the mailing list yet.
This post was updated on .
I am trying to create a new domain object by sending the following JSON to the server - this is being handled by the JAX-RS plugin.
{ "class": "Contact", "phoneNumbers": [ {"class":"Phone","number":"651-489-9601","type":{"class":"PhoneType","id":1}} ], "username": "1@1.com", "password": "0123456789" } However, I get the following error: Failed to convert property value of type 'org.codehaus.groovy.grails.web.json.JSONArray' to required type 'java.util.List' for property 'phoneNumbers'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.codehaus.groovy.grails.web.json.JSONObject] to required type [net.limosoft.Phone] for property 'phoneNumbers[0]': no matching editors or conversion strategy found Omitting the one-to-many list of phone numbers creates the contact as expected. Submitting a form to the standard ContactController with a phoneNumbers array also creates the contact and associated phone numbers as expected. So what is going on with the handling of this JSON? I have searched for this error message with no success in finding the cause of the problem. From experience it looks like a Spring error message that I have seen when Spring does not know now to inject a dependency. Rendering a previously saved Contact with associated phone numbers looks similar to this JSON except, as expected, the Phone number is just the class and the ID number. Any help or suggestions would be greatly appreciated. |
|
Nothing? No suggestions at all?
I hate to abandon Grails for this application, but I need a resftul JSON API that works and that is debugable. Somehow that doesn't seem like too much to ask for. |
|
You got no responses because nobody saw it - the original message is only available on Nabble. Try re-sending now that your messages are going through to the mailing list.
Burt
|
|
Thanks Burt.
I resent to the group but it does not seem to be going through. Not sure what the issue is. |
|
Replaying with original question since replies seem to be working.
I am trying to create a new domain object by sending the following JSON to the server - this is being handled by the JAX-RS plugin. { "class": "Contact", "phoneNumbers": [ {"class":"Phone","number":"651-489-9601","type":{"class":"PhoneType","id":1}} ], "username": "1@1.com", "password": "0123456789" } However, I get the following error: Failed to convert property value of type 'org.codehaus.groovy.grails.web.json.JSONArray' to required type 'java.util.List' for property 'phoneNumbers'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.codehaus.groovy.grails.web.json.JSONObject] to required type [net.limosoft.Phone] for property 'phoneNumbers[0]': no matching editors or conversion strategy found Omitting the one-to-many list of phone numbers creates the contact as expected. Submitting a form to the standard ContactController with a phoneNumbers array also creates the contact and associated phone numbers as expected. So what is going on with the handling of this JSON? I have searched for this error message with no success in finding the cause of the problem. From experience it looks like a Spring error message that I have seen when Spring does not know now to inject a dependency. Rendering a previously saved Contact with associated phone numbers looks similar to this JSON except, as expected, the Phone number is just the class and the ID number. Any help or suggestions would be greatly appreciated. |
|
There's a fair bit of information out there about marshalling and unmarshalling from java objects to xml and json. Â I'm not sure what the process looks like for going from json back to java objects. Â One could hope that the JSON converter would use the same mechanism that is used for binding normal HTTP request body content to command objects, such that providing a PropertyEditorRegistry with PropertyEditors for the classes you need to convert would be sufficient for allowing the framework to function as expected. Â That sort of seems likely based on the message "no matching editors or conversion strategy found." Â However, there doesn't appear to be any way to provide a property editor that is local to a single instance of the JSON converter, so if that mechanism works, it must only work via global changes, which could have all kinds of side effects elsewhere in your code (something like this: http://blog.armbruster-it.de/2010/01/customizing-grails-data-binding-with-a-groovy-propertyeditor/ ). The fact that the normal HTTP binding mechanism works for the same object seems to suggest that the problem may be that the JSON representation of the Phone object is different from the one used for normal HTTP conversion. Â Perhaps try putting each phone number in the json object in the exact same format that it is received in normal HTTP traffic and see if that works? Â I'm just guessing here, but it wouldn't take too long to try that, I'd think.
On Tue, Aug 7, 2012 at 1:08 AM, bighappy1970 <[hidden email]> wrote: Replaying with original question since replies seem to be working. |
|
From what I have been able to discover, JSON support in grails is not
equivalent to the support for query parameters. Looking through the defects open for JSON it does not look like it will ever be equivalent. I believe I have two possible approaches if I want to stick with Grails and a JSON API - Dig into the data binding and find a way to fix the JSON issues as I uncover them. In this case, when the JSON is converted to a params map, the phoneNumbers paramater value is JSONArray, and binding does not know what to do with a JSONArray. If this same information is submitted via standard form submission, the phoneNumbers parameter is a GrailsParameterMap Writer a converter to transform the JSON to a parameter map identical to the traditional form submission. Does anyone have any experience they are willing to share with either of these tasks? Thanks -- View this message in context: http://grails.1312388.n4.nabble.com/JSON-Unable-to-Marshall-to-a-Domain-Object-no-matching-editors-or-conversion-strategy-found-tp4632722p4633088.html Sent from the Grails - user mailing list archive at Nabble.com. --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
In reply to this post by ideasculptor
sorry if this is a repost - this keeps telling me that my posts are not accepted by the mailing list.
From what I have been able to discover, JSON support in grails is not equivalent to the support for query parameters. Looking through the defects open for JSON it does not look like it will ever be equivalent. I believe I have two possible approaches if I want to stick with Grails and a JSON API - Dig into the data binding and find a way to fix the JSON issues as I uncover them. In this case, when the JSON is converted to a params map, the phoneNumbers paramater value is JSONArray, and binding does not know what to do with a JSONArray. If this same information is submitted via standard form submission, the phoneNumbers parameter is a GrailsParameterMap Writer a converter to transform the JSON to a parameter map identical to the traditional form submission. Does anyone have any experience they are willing to share with either of these tasks? Thanks |
|
In reply to this post by bighappy1970
On Sun, Aug 12, 2012 at 11:11 PM, bighappy1970 <[hidden email]> wrote:
I don't have anything more to add, except that this seems likely to be functionality that would benefit the community as a whole if you can come up with a solution that's sufficiently flexible and grails-y. Â I've always built my apps such that client to server communication is via normal http POST/GET requests, but server to client communication is via json, so I don't have direct experience with your problem. Â For the most part, I've always done it that way precisely because no framework has offered a sufficiently flexible solution to the problem you are having that I felt I'd be able to use it without writing a lot of code to work around issues. Â It's the same reason I tend to POST to command objects rather than directly to domain objects and, more often than not, copy domain objects to a DTO prior to serializing as JSON to the client. Â I wind up with more control and fewer lines of code that are purely there to work around problems. One could argue that my command objects and DTOs are all workaround, but at least their presence and function is a little more obvious and I actually wind up with greater consistency from one controller to the next.
Sorry to not be able to offer you anything more constructive. --sam |
|
Thanks for the info Sam. I've only been working with Grails for a few weeks, so I didn't know what I was getting into. =) I certainly didn't expect any issues with JSON.
After a bit if digging, I discovered that JSONParsingParameterCreationListener has no chance of actually "Automatically parsing JSON into the params object." as the documentation claims unless you are dealing with single-level object map. I played around a bit and wrote my own JSON-to-params converter (not at all difficult) - using this new converter I am able to construct a params map that will successfully construct the Contact domain object from the JSON specified in the original question. I have a lot of testing before I can say for sure that I have a complete solution, but so far it appears to work for any data binding supported by traditional form submission. I'm interested in learning more about your command objects and DTO patterns - being very new to Grails I don't really know any of the "best practices" implementation patterns (or the reasons for them) - is there some sites or sample code you can share? Thanks again. |
|
I've been struggling with this same issue for quite a while and have not found a useful solutions.
Most recently, I've been unable to get the nested binding to work and have reverted to iterating over the JSONArray in code and creating the necessary sub-objects in that way. This has been as close as I came to getting it working in the way I was hoping it would: http://stackoverflow.com/questions/11513416/grails-json-binding-to-linkedhashset-instead-of-jsonarray-for-deeply-nested-rela I'd be very interested in finding out more as to how you wrote the JSON-to-params converter. Would be great if you were willing to share with the mailing list. |
|
Hi Cowper,
Sorry to hear that you are having the same issue - it is a real pain in the...well, you know. =) I took a shot at documenting the issues and providing source code on my website - have a look at http://www.dalelotts.com/software-architect/grails and let me know if you have any questions. |
|
thanks bighappy ... I need to set aside some time to go through your article ...
in the meantime were you also encountering as issue with IDs for related objects? For example: class PersonCommand { //gender is another domain object Gender gender } When Grails attempts to bind JSON where "gender.id" is null an "object type micmatch" exception occurs. This happens even before any of the validators can be called. It's related to the fact the "gender.id" is bound to JSONObject$Null and the marshaller pukes when trying to associate this to the related object. This has been the bane of my life. Have you come across that scenario and do you know if your code handles that? thanks ... |
|
In reply to this post by bighappy1970
one question after looking at the code ... the methods
readFromJson appendMapValues Do these need to be called manually from code as part of the controller? Not sure where to put them otherwise? In my scenario, I'm using the "resource" URL mapping (http://grails.org/doc/1.3.7/guide/13.%20Web%20Services.html) which automatically does the binding to JSON. It's at this point that my pain has been. Is it possible to plug your code into the framework so that it happens as part of the automatic binding? thanks again ... |
|
Hi Cowper,
Unfortunately, I don't think that this code can be used with automatic JSON binding because the automatic data binding uses the Grails native JSON parser. Trying to data bind to the result from the Grails native parser will not work with nested domain objects, the only way around this is to use a different JSON parser that can return a format that will work for data binding (i.e. a Map with the correct keys and values to represent the nested domain object). As you pointed out, the trick is to figure out where to put the readFromJson call. In my case, I am using the JAX-RS plugin (See http://grails.org/plugin/jaxrs) - I used this approach because it gives me greater control than the URL mappings. I can also provide my own reader for binding. =) If you are using the JAX-RS plugin, copy the DomainObjectReader class from the plugin into your grails-app\providers directory, then replace the readFromJson method with the code from my post (I will update the post with this info and the new DomainObjectReader file.) If you want to stick with the URL mappings, I think you need to remove the parseRequest:true from the mapping, then in the controller parse the JSON from the request into your domain object by calling readFromJson - if you can post a sample project that demonstrates your problem I can update it with my fix - Sorry, I just don't know enough about the approach you are using to tell you how to plug in the fix.
|
|
hey, for what it's worth, I added a test case for a related JSON marshalling problem to the JIRA:
http://jira.grails.org/browse/GRAILS-9391#comment-72179 This is related to when the child in a parent child is null, the automatic marshalling fails. Really adding it here to provide a trail in the hope that anyone with the same issue can find the JIRA. C |
| Powered by Nabble | Edit this page |
