Send a GET request in Java
What is a GET Request?
A GET Request is one of the most popular HTTP methods which is used to request data from a server. A GET request does not modify the data and only retrieves it, that's why it is considered to be safe and in some cases can be cached since multiple identical requests should have the same effect as a single request.
1. How to send a GET request in Java?
1.1. Preparing a request
HttpRequest request = HttpRequest.newBuilder()
.GET()
.uri(URI.create("https://api.restful-api.dev/objects/7"))
.build();
In order to represent a request that we are going to send, we can leverage the HttpRequest object which was introduced in Java 11 version.
Depending on the REST API to which you are going to send a GET request, you might need to provide some extra configurations, like for example an authorization token which might be part of the Request Headers if REST API requires it. But in our case, we don't require any authorization tokens and we just simply provide a request type (GET) and the request URL ("https://api.restful-api.dev/objects/7"). P.S. number '7' which is part of this URL represents a unique ID of a resource that we are going to request.
1.2. Sending a request and printing a Response
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
The GET request now can be sent using a HttpClient which was also introduced in Java 11 version. By storing a response as a variable, we can print the response code and a response body. If the response code which we got is equal to 200, it would mean that our request was successful, if we got something else, it would mean that there was a problem with a request.
If the request was successful, the response.body() would represent the resource that we have requested from the REST API. In this case, the resource with unique ID = 7 looks like this:
{
"id": "7",
"name": "Apple MacBook Pro 16",
"data": {
"year": 2019,
"price": 1849.99,
"CPU model": "Intel Core i9",
"Hard disk size": "1 TB"
}
}
2. How to convert a response from a request to a Java Object?
2.1. Creating an Object
Sending a request is a good thing, but what do you do with a response? Since it's Java and since it is an Object-oriented programming language, most probably you would like to convert a response from a GET request to a POJO (Plain old Java object), right?
One of the first steps would be to obviously create this Object which you would be able to leverage later on in any way you want. This Object should obviously represent a response body which you expect from a REST API.
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.Map;
@JsonIgnoreProperties(ignoreUnknown = true)
public class MyObject {
private String name;
private Map<String, Object> data;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, Object> getData() {
return data;
}
public void setData(Map<String, Object> data) {
this.data = data;
}
@Override
public String toString() {
return "MyObject{" +
"name='" + name + '\'' +
", data=" + data +
'}';
}
}
You can notice an import from an external library and also JsonIgnoreProperties annotation, what it all means, and why do we need it?
2.2. Jackson library
Jackson library is a very useful external library that provides a convenient way to map JSON data to Java objects. In the example of a POJO which we created above, you can see a JsonIgnoreProperties annotation. This annotation would help us to ignore any unknown properties in a JSON string (Response Body type in our case) during deserialization. Imagine that you get a response body with 50 different attributes and some of them are even optional and you are just interested in 5 particular attributes, how would you handle it? Would you create a POJO with all of the 50 different attributes even though you need 5 of them? Would you get some errors during the decentralization if you see unrecognized attributes? Not if you leverage the Jackson annotations properly because they are very useful!
Jackson is an external library, so you might need to import it. Here is an example of how to add it to your depedencies:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.1</version>
</dependency>
2.3. Object Mapper
Now we are ready to convert our response to a Java Object. For that, we can use an ObjectMapper class which also comes from a Jackson library.
If we create a plain instance of ObjectMapper class, we can use this instance to just simply call readValue method and pass the response body and an Object class to which we want to map our response. This is all that we need to do to convert a JSON response to a Java Object!
ObjectMapper objectMapper = new ObjectMapper();
MyObject myObject = objectMapper.readValue(response.body(), MyObject.class);
3. Putting everything together
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Main {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.GET()
.uri(URI.create("https://api.restful-api.dev/objects/7"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
ObjectMapper objectMapper = new ObjectMapper();
MyObject myObject = objectMapper.readValue(response.body(), MyObject.class);
System.out.println("Response: " + myObject.toString());
}
}