11

I'm trying to get request params passed by PUT request, at Grails-based app.

I'm using following client code to make request:

$.ajax({
    url: 'api/controllerName/anId',
    type: 'PUT',
    data: $('form').serialize()
})

with following mapping:

"/api/$controller/$id?" {
    action = [ GET: "read", POST: "create", PUT: "update", DELETE: "delete"]
}

But my controller's action receives empty params list, with only id value. I tried to put it content to logs and saw only:

[id:anId, action:[GET:read, POST:create, PUT:update, DELETE:delete], controller:controllerName]

and request.getParameterNames() returns empty list of values.

As I see from FireBug, request contains this params, and have Content-Type as application/x-www-form-urlencoded; charset=UTF-8

If I'm using GET/POST method - everything is working as expected, I can get all passed parameters.

How I can get access to passed parameters?

Update: I've just figured that PUT implies passing data as JSON/XML in body. Btw, this question is still actual, just in case

Igor Artamonov
  • 35,450
  • 10
  • 82
  • 113
  • So the request *does* actually make it to your `update` method (i.e. gets routed via the mappings with the `PUT` method correctly)? – Rob Hruska Aug 25 '11 at 19:46
  • Ok, I was just ruling out that it might be something with the browser and a not-as-commonly-supported PUT method. – Rob Hruska Aug 25 '11 at 20:27
  • What are you actually trying to do here that requires a `PUT`? How are you trying to pass the parameters? As part of the Request-URI (like `GET`), or in the body (like `POST`)? Looking at what you say about your Content-Type header, it's being transmitted in the body - this is not really a valid use of the `PUT` method (neither would passing them in the Request-URI). Why are you not just using `GET` or `POST`? – DaveRandom Aug 25 '11 at 20:55
  • 1
    Dave, thank! Yes, i've passed them as body (as it implemented by jQuery). I'm using PUT just because i'm trying to make valid REST API. What you can suggest at this case? – Igor Artamonov Aug 25 '11 at 21:01
  • While I would be the first to admit that I am not exactly a RESTful developer, I don't understand why you couldn't just GET or POST the data... What is the data, and what is the conatraint that makes PUT the best option? – DaveRandom Aug 25 '11 at 22:24
  • 1
    I can use GET/POST, but it'll be invalid RESTful API. As I know, PUT was made specifically for this, for updating existing object, by the url. You can read more about RESTful https://www.ibm.com/developerworks/webservices/library/ws-restful/ – Igor Artamonov Aug 25 '11 at 22:38
  • 1
    @DaveRandom, good answer on POST vs PUT: http://stackoverflow.com/questions/630453/put-vs-post-in-rest – beny23 Aug 25 '11 at 22:55

2 Answers2

10

I had the exact same issue today and was able to fix it. I did an ajax request with JQuery to a Grails RESTful WebService (method: "PUT"), but the parameter map was empty.

Just want to share my solution here.

I had to JSON.stringify my data and set the contentType to "application/json" and then use request.JSON (as suggested before) in my Grails controller.

example (JQuery Ajax Request):

$.ajax({
        url: "/entries/" + id,
        contentType: "application/json",
        type: "PUT",
        dataType: "json",
        data: JSON.stringify({'name' : name, 'date': date}),
        success: function(msg) {
            console.log('updated...')
            $.mobile.changePage($('#list'));
        }

afterwards I could use:

request.JSON

in my Controller in order to get the data sent by the ajax request (params was still empty). If I did not use JSON.stringify and set the content type, I had the following Grails error:

Error 2012-04-03 13:50:20,046 [http-bio-8080-exec-3] ERROR errors.GrailsExceptionResolver  - IllegalStateException occurred when processing request: [PUT] /entries/2
getReader() has already been called for this request. Stacktrace follows:
Message: getReader() has already been called for this request

I'm using Grails 2.0.1 and JQuery 1.7.1

mburri
  • 166
  • 2
  • 7
  • dude, @mburri you're awesome. i was having the exact same problem and it was bugging the heck out of me that i had to use POST for an update. the interesting thing is that "contentType: 'application/json'" on the client wasn't required when i did a PUT. request.JSON still contained the data. but when i did a POST, "contentType: 'application/json'" was required. but of course it's always best practice to state what you're sending. thanks a lot! – Khon Lieu Jul 08 '12 at 05:02
  • +1 For PUT both contentType and stringify() must be used, thanks for the answer! – dbrin Nov 07 '13 at 17:16
  • I'm wonder if this is a Jquery+grails issue because the grails side works fine when I tested with curl but not with jquery. – Teo Choong Ping Nov 26 '13 at 07:17
2

Try request.JSON (or request.XML) instead of params.

Dem0n3D
  • 23
  • 1
  • 2