Wednesday, September 15, 2010

REST XML parsing with Grails 1.3.4

We encountered an issue with Grails 1.3.4 where we found that the XML packet was not parsed and added to the params variable in the controller.

The grails manual has a section which describes how to do REST web services. We followed the instructions but we weren't able to get the automatic data binding to our domain class to work. A fix seems to be on the way but in the mean time, the code below provides a workaround for the issue:

private populateParamsFromXML(xml,map) {              
        def rootName = xml.name()
        //check if params is already populated
        if(map[rootName])
            return
        def xmlMap = [:]
        map[rootName] = xmlMap          
        map = xmlMap
        for (child in xml.children()) {
            // one-to-ones have ids
            if (child.@id.text()) {
                map["${child.name()}.id"] = child.@id.text()
                def childMap = [:]
                def key 
                map[child.name()] = childMap
                populateParamsFromXML(child, childMap)
            }
            else {
                map[child.name()] = child.text()
            }
        }
    }

It should be called in a controller action before the params variable is used to populate a domain class.

populateParamsFromXML(request.XML,params)

I hope you found the post useful. You can subscribe via email or subscribe via a feed reader to get relevant updates from this blog. Have a nice day.

3 comments:

  1. This is documented in the manual, see http://www.grails.org/doc/latest/guide/2.%20Getting%20Started.html#2.2%20Upgrading%20from%20previous%20versions%20of%20Grails :
    "Incoming XML requests are now no longer automatically parsed. To enable parsing of REST requests you can do so using the parseRequest argument inside a URL mapping"

    ReplyDelete
  2. Hi Lari Hotari,

    I followed this entry in the users guide: http://grails.org/doc/1.3.4/guide/13.%20Web%20Services.html#13.1%20REST

    And yes, I am aware of the parseRequest argument and yes, i tried it and it did NOT work. I'll upload a sample project somewhere if you'd like to see what I did. I also found an entry in 1.3.5 release notes pertaining to this issue and that its already fixed.

    ReplyDelete
  3. Has been fixed in Grails 1.3.5+, parseRequest:true still required though. See http://jira.grails.org/browse/GRAILS-6614

    ReplyDelete