1

Grails 2.4.2

I have a UserController and in its save method, I need to pass in an Organization ID along with the User data so that I can find the Organization and then create the many-to-many relationship. So I have something like this...

def save(User user) {
    def orgExternalId = request.JSON.orgExternalId
    userService.save(user, orgExternalId)
    // more boilerplate
}

I'm POST'ing the following json:

{ 
  "orgExternalId" : "123445", 
  "firstName": "gregg", 
  "lastName": "bolinger",
  "username": "gdboling"
}

However, I'm not getting the orgExternalId out of the JSON in my controller. Also, if I inspect the JSON, it is empty, but the User domain is populated correctly. My assumption at this point is I'm going to have to use a Command Object or I could put the orgExternalId in the header, but I'd like to know if there is another way.

Gregg
  • 34,973
  • 19
  • 109
  • 214
  • I'm confused, you show some JSON with `"orgExternalId" : "123445"` but you then say when you inspect the JSON `orgExternalId` is empty... JSON doesn't just disappear, either you're not actually POSTing that JSON or its getting modified somewhere... – nickdos Aug 12 '14 at 22:43
  • Both are true. I *think* that grails possibly empties the JSON object when it populates User automatically. But no way of confirming that at the moment. I do know that I'm sending it and that User contains all the appropriate values from the rest of the JSON. – Gregg Aug 12 '14 at 22:46
  • Try `log.debug "JSON = ${request.JSON}` at the top of the controller action... – nickdos Aug 12 '14 at 22:48
  • It comes back as [:]. – Gregg Aug 12 '14 at 22:48
  • Show us your code for how the POST is being sent to the controller - is it via JS or a regular form POST? EDIT: forget that it must be JS... – nickdos Aug 12 '14 at 22:50
  • I'm using Chrome's Postman extension. I promise you it is being sent correctly. I know you're trying to help, but you're trying to solve the wrong problem. I believe this is just how grails treats JSON when parsing requests via their resources mechanism. Just looking for confirmation and/or an alternate way of doing this. – Gregg Aug 12 '14 at 22:52
  • I agree, it must be the bean binding... you could try removing the action method argument (User) and bind the User manually... see http://stackoverflow.com/a/15072063/249327 – nickdos Aug 12 '14 at 22:53
  • 1
    You cannot get JSON from the request anymore if you have used the domain class as Command Object. Request payload has already been read by now as part of the data binding and the payload has has been removed from `request`. You can manually try binding once you have retrieved the portion of the payload that is extra. – dmahapatro Aug 13 '14 at 01:00

1 Answers1

1

Have a look at Binding The Request Body To Command Objects. Mainly:

Note that the body of the request is being parsed to make that work. Any attempt to read the body of the request after that will fail since the corresponding input stream will be empty. The controller action can either use a command object or it can parse the body of the request on its own (either directly, or by referring to something like request.JSON), but cannot do both.

I wasn't sure if I would find this verbiage while adding answer as a comment. :)

dmahapatro
  • 49,365
  • 7
  • 88
  • 117