Groovy HTTP and REST Calls
last modified October 15, 2026
Scripts often need to call web services: fetch JSON from a REST API, send data
to a server, or check whether a site responds. Groovy makes this easy because it
adds helpers to the standard Java networking classes. In this tutorial, we make
HTTP requests with URL.text and with HttpURLConnection
for full control over headers, methods, and status codes. The examples use the
public test API at jsonplaceholder.typicode.com, which accepts
requests without an API key.
Reading a URL with URL.text
The simplest way to fetch a resource is the text property of a
URL. Groovy opens the connection, reads the response body with the
default encoding, and returns it as a string.
def url = new URL('https://jsonplaceholder.typicode.com/todos/1')
println url.text
The URL points to a to-do item. url.text performs an HTTP GET and
returns the JSON body, which the script prints unchanged.
$ groovy UrlText.groovy
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
Timeouts and Headers with getText
URL.text has no timeouts and no way to set headers. The
getText method accepts a map with these options, and is the better
choice for scripts that call remote servers:
def url = new URL('https://jsonplaceholder.typicode.com/todos/3')
def timed = url.getText(connectTimeout: 5000, readTimeout: 5000,
requestProperties: ['Accept': 'application/json'])
println timed.contains('"id": 3')
try {
new URL('https://jsonplaceholder.typicode.com/todos/99999').text
} catch (FileNotFoundException e) {
println "FileNotFoundException: ${e.message}"
}
connectTimeout and readTimeout are given in
milliseconds. Without them, a stalled server can block the script for a long
time. requestProperties adds HTTP headers.
new URL('https://jsonplaceholder.typicode.com/todos/99999').text
When the server answers with an error status such as 404, reading
the body with text throws an exception. For a 404, Java throws
FileNotFoundException, which is a known quirk of
HttpURLConnection; other error codes usually produce an
IOException instead.
$ groovy UrlGetText.groovy true FileNotFoundException: https://jsonplaceholder.typicode.com/todos/99999
GET Requests with HttpURLConnection
HttpURLConnection is the standard Java class for HTTP. It lets us
set the method, read the status code and response headers, and handle errors
ourselves. Groovy's openConnection method returns it from a
URL.
import groovy.json.JsonSlurper
def conn = new URL('https://jsonplaceholder.typicode.com/todos/1').openConnection()
conn.requestMethod = 'GET'
conn.setRequestProperty('Accept', 'application/json')
conn.connectTimeout = 5000
conn.readTimeout = 5000
println "Status: ${conn.responseCode}"
println "Type: ${conn.contentType}"
def body = conn.inputStream.withReader('UTF-8') { it.text }
def todo = new JsonSlurper().parseText(body)
println "${todo.id}: ${todo.title} (done=${todo.completed})"
conn.disconnect()
The requestMethod, request headers, and timeouts are set as
properties of the connection. Reading responseCode sends the
request and returns the HTTP status. JsonSlurper parses the body
into maps and lists, as shown in the
Groovy JsonSlurper tutorial.
def body = conn.inputStream.withReader('UTF-8') { it.text }
withReader opens the stream, passes a reader to the closure, and
closes the stream when the closure returns. Specifying the encoding avoids
depending on the platform default.
$ groovy HttpGet.groovy Status: 200 Type: application/json; charset=utf-8 1: delectus aut autem (done=false)
POST Requests with a JSON Body
To send data, set doOutput to true, write the body to
outputStream, and then read the response. Groovy's
JsonOutput converts a map to a JSON string.
import groovy.json.JsonOutput
def conn = new URL('https://jsonplaceholder.typicode.com/posts').openConnection()
conn.requestMethod = 'POST'
conn.doOutput = true
conn.setRequestProperty('Content-Type', 'application/json; charset=UTF-8')
def payload = JsonOutput.toJson([title: 'Hello', body: 'From Groovy', userId: 7])
conn.outputStream.withWriter('UTF-8') { it.write(payload) }
println "Status: ${conn.responseCode}"
println conn.inputStream.withReader('UTF-8') { it.text }
requestMethod = 'POST' sets the HTTP method, and
doOutput = true allows the script to write a request body. The
Content-Type header tells the server that the body is JSON.
The server responds with status 201 Created and returns the new
resource, including an id assigned by the server.
$ groovy HttpPost.groovy
Status: 201
{
"title": "Hello",
"body": "From Groovy",
"userId": 7,
"id": 101
}
Handling Error Status Codes
A 404 or 500 response is not a network failure, so the
connection works, but conn.inputStream throws for these codes. To
read the error body, check the status first and use errorStream
when it is 400 or higher.
def conn = new URL('https://jsonplaceholder.typicode.com/todos/99999').openConnection()
conn.connectTimeout = 5000
conn.readTimeout = 5000
def code = conn.responseCode
println "Status: $code"
def stream = code >= 400 ? conn.errorStream : conn.inputStream
def text = stream?.withReader('UTF-8') { it.text } ?: ''
println "Body: '${text}'"
The script reads the status code once, then picks the right stream. The
?. and ?: operators handle a missing stream: the
errorStream can be null when the server sends no body.
Each stream can be read only once. Calling .text a second time on
the same stream fails with stream is closed, so store the text in a
variable if you need it twice.
$ groovy HttpStatus.groovy
Status: 404
Body: '{}'
Best Practices
- Always set timeouts. Use
connectTimeoutandreadTimeoutso a slow server cannot hang the script. - Check the status code. A response body is not proof of
success; compare
responseCodeagainst the expected value. - Specify the charset. Pass
'UTF-8'towithReaderandwithWriterinstead of relying on the platform default. - Close connections. Use
withReaderandwithWriter, or calldisconnect, so sockets are released. - Use
URL.textonly for simple GETs. For headers, methods other than GET, or error handling, useHttpURLConnection.
Source
This tutorial showed how to read URLs with URL.text and
getText, send GET and POST requests with HttpURLConnection,
and handle error status codes.
Author
List all Groovy tutorials.