I’m trying to send a POST using Groovy HTTPBuilder but the data I want to send is already URL-encoded so I want HTTPBuilder to POST it as is. I tried the following:
def validationString = "cmd=_notify-validate&" + postData
def http = new HTTPBuilder(grailsApplication.config.grails.paypal.server)
http.request(Method.POST) {
uri.path = "/"
body = validationString
requestContentType = ContentType.TEXT
response.success = { response ->
println response.statusLine
}
}
But it gives me a NullPointerException:
java.lang.NullPointerException
at groovyx.net.http.HTTPBuilder$RequestConfigDelegate.setBody(HTTPBuilder.java:1200)
Since you’re using pre-encoded form values you cannot use the default map-based content type encoder. You must specify the content type so the
EncoderRegistryknows how to handle the body.You may create the HttpBuilder with a content type that specifies the body is a URL-encoded string:
Or make the request passing the content type explicitly:
For reference, here’s how I figured it out–I didn’t know before I read the question.
requestmethod’s API docs to see what the closure was expected to contain. I’ve usedHTTPBuilderonly in passing, so I wanted to see what, specifically, thebody“should” be, or “may” be, and if the two were different.RequestConfigDelegateclass and said the options were discussed in its docs.RequestConfigDelegate.setBodymethod, which is what thebodysetter is, states the body “[…] may be of any type supported by the associated request encoder. That is, the value ofbodywill be interpreted by the encoder associated with the current request content-type.”EncoderRegistryclass. It has anencode_formmethod taking a string and states it “assumes the String is an already-encoded POST string”. Sounds good.HttpBuilderinner class method,RequestConfigDelegate.getRequestContentType, which in turn had a link to theContentTypeenum.URLENCvalue that led me to believe it’d be the best first guess.HTTPBuilderctor taking a content type, and that worked.requestmethods and noticed there’s a version also taking a content type.I’d guess the total time was ~5-10 minutes, much shorter than it took to type up what I did. Hopefully it’ll convince you, though, that finding this kind of stuff out is possible via the docs, in relatively short order.
IMO this is a critical skill for developers to groom, and make you look like a hero. And it can be fun.