Search code examples
httpgroovygrails

Groovy/Grails HTTPBuilder automatic JSON parsing


Groovy 2.4.14, Grails 2.5.6, JVM 1.8, MacOS

I'm trying (and succeeding) to use a UPS (United Parcel Service) API to obtain tracking information given a tracking number. The code works, and UPS returns a JSON string (and Content-Type: application/json). I can parse the JSON and I get exactly what I need.

However, I would kind-of prefer that HTTPBuilder do the JSON parse, because what it gives me is somewhat odd. I get back a HashMap, with the first key being the JSON body, and the value null. Like this:

{ "JSON stuff": null }

So I can parse that and get a usable structure with the normal Groovy tools:

def json = JSON.parse(data.keySet()[0])

The only thing I suspected might help was to set the "Accept" header to JSON, but that has no effect.

Here's the HTTPBuilder code:

def trackingGroup(String tracking) {
    def result;

    try {
        HTTPBuilder http = new HTTPBuilder(urlbase)
        http.request(Method.GET, ContentType.URLENC) { req ->
            uri.path = "/api/track/v1/shipment/details/${tracking}";

            requestContentType = ContentType.URLENC;
            headers['Authorization'] = "Bearer ${TOKS.getToken()}"
            headers['User-Agent'] = "Me";
            headers['Accept'] = ContentType.JSON;
            headers['transId'] = "testing"
            headers['transactionSrc'] = "testing"

            response.success = { resp, json ->
                result = json
            }
            response.failure = { resp, json ->
                result = json
            }
        }
    }
    catch (error) {
        error.printStackTrace();
        result = null
    }

    if (result == null) return "total failure";

    result = JSON.parse(result.keySet()[0])

    List alltrack = [];
    result.trackResponse.shipment.each { shipment ->
        shipment.package.each { p ->
            alltrack << p.trackingNumber
        };
    };

    return alltrack;
}

I have been able to find no good documentation anywhere about my Groovy/Grails version for the groovyx.net.http package, so what I'm asking is if there's a thing I can call in the closure parameter to the .request() call to tell it to assume JSON and parse it.


Solution

  • Try passing ContentType.JSON instead of ContentType.URLENC to the http.request call. According to the documentation it refers to the expected content type.