Posting JSON data with Groovy's HTTPBuilder
Asked Answered
P

5

13

I've found this doc on how to post JSON data using HttpBuilder. I'm new to this, but it is very straightforward example and easy to follow. Here is the code, assuming I had imported all required dependencies.

def http = new HTTPBuilder( 'http://example.com/handler.php' )
http.request( POST, JSON ) { req ->
    body = [name:'bob', title:'construction worker']

     response.success = { resp, json ->
        // response handling here
    }
}

Now my problem is, I'm getting an exception of

java.lang.NullPointerException
    at groovyx.net.http.HTTPBuilder$RequestConfigDelegate.setBody(HTTPBuilder.java:1131)

Did I miss something? I'll greatly appreciate any help you can do.

Peugia answered 26/7, 2011 at 14:35 Comment(1)
the answers seem to be outdated; the import mentioned in the answers is no longer found; to see how to post json data in groovy, try this: #25693015Gast
P
18

I took a look at HttpBuilder.java:1131, and I'm guessing that the content type encoder that it retrieves in that method is null.

Most of the POST examples here set the requestContentType property in the builder, which is what it looks like the code is using to get that encoder. Try setting it like this:

import groovyx.net.http.ContentType

http.request(POST) {
    uri.path = 'http://example.com/handler.php'
    body = [name: 'bob', title: 'construction worker']
    requestContentType = ContentType.JSON

    response.success = { resp ->
        println "Success! ${resp.status}"
    }

    response.failure = { resp ->
        println "Request failed with status ${resp.status}"
    }
}
Planimetry answered 26/7, 2011 at 15:2 Comment(7)
Thank you for the response, but still no good :( java.lang.NullPointerExceptionat groovyx.net.http.HTTPBuilder$RequestConfigDelegate.setBody(HTTPBuilder.java:1147) Had you tried that example on your machine? Does it work? And also, on the value of uri.path, does it need to be an existing path?Peugia
Looks like you got farther along; the new NPE is when it's trying to find the appropriate response handler. The request probably failed, so you'll want a failure handler. I'll update my example.Planimetry
"on the value of uri.path, does it need to be an existing path" - If the host doesn't exist, you'll get some sort of connection error. If it does exist but the resource you're POSTing to doesn't exist, you'll get an HTTP 404 or something.Planimetry
No good at all, I'm still getting the same NPE using the example that you had provided. I think exception gets thrown before reaching the failure handler line.Peugia
It worked for me. I had an NPE at groovyx.net.http.HTTPBuilder$RequestConfigDelegate.setBody(HTTPBuilder.java:1200) and was fixed by adding the requestContentType. ThanksPeristalsis
If you are running groovy file standalone. Remember to import HTTPBuilder into groovy file @Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7.1')Revert
the only problem, if I try to post object as json, it puts empty string on null String fields, but I really need nullsEndocrinology
K
8

I had the same problem a while ago and found a blog that noted the 'requestContentType' should be set before 'body'. Since then, I've added the comment 'Set ConentType before body or risk null pointer' in each of my httpBuilder methods.

Here's the change I would suggest for your code:

import groovyx.net.http.ContentType

http.request(POST) {
    uri.path = 'http://example.com/handler.php'
    // Note: Set ConentType before body or risk null pointer.
    requestContentType = ContentType.JSON
    body = [name: 'bob', title: 'construction worker']

    response.success = { resp ->
        println "Success! ${resp.status}"
    }

    response.failure = { resp ->
        println "Request failed with status ${resp.status}"
    }
}

Cheers!

Kinsley answered 26/7, 2011 at 14:35 Comment(2)
the only problem, if I try to post object as json, it puts empty string on null String fields, but I really need nullsEndocrinology
Hi dmitryvim, Are you talking about the POST request's response JSON? Or are you attempting to set string fields within the body JSON to null?Kinsley
A
2

If you need to execute a POST with contentType JSON and pass a complex json data, try to convert your body manually:

def attributes = [a:[b:[c:[]]], d:[]] //Complex structure
def http = new HTTPBuilder("your-url")
http.auth.basic('user', 'pass') // Optional
http.request (POST, ContentType.JSON) { req ->
  uri.path = path
  body = (attributes as JSON).toString()
  response.success = { resp, json -> }
  response.failure = { resp, json -> }
}    
Allstar answered 21/11, 2013 at 14:59 Comment(0)
L
1

I found an answer in this post: POST with HTTPBuilder -> NullPointerException?

It's not the accepted answer, but it worked for me. You may need to set the content type before you specify the 'body' attribute. It seems silly to me, but there it is. You could also use the 'send contentType, [attrs]' syntax, but I found it more difficult to unit test. Hope this helps (late as it is)!

Lapland answered 2/10, 2012 at 17:3 Comment(0)
A
-1

I gave up on HTTPBuilder in my Grails application (for POST at least) and used the sendHttps method offered here.

(Bear in mind that if you are using straight Groovy outside of a Grails app, the techniques for de/encoding the JSON will be different to those below)

Just replace the content-type with application/json in the following lines of sendHttps()

httpPost.setHeader("Content-Type", "text/xml")
...
reqEntity.setContentType("text/xml")

You will also be responsible for marshalling your JSON data

 import grails.converters.*

 def uploadContact(Contact contact){  
   def packet = [
      person : [
       first_name: contact.firstName,
       last_name: contact.lastName,
       email: contact.email,
       company_name: contact.company
      ]
   ] as JSON //encode as JSON
  def response = sendHttps(SOME_URL, packet.toString())
  def json = JSON.parse(response) //decode response 
  // do something with json
}
Apophysis answered 31/1, 2012 at 18:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.