RestClient - Unirest fork
Unirest is a set of lightweight HTTP libraries available in multiple languages, built and maintained by Mashape, who also maintain the open-source API Gateway Kong.
This fork is intended to fix the bugs left by the original authors, improve the API, and provide continuous support. Improvements, new ideas, and bug reports are very welcome.
Apart from the features provided by the original Unirest Java, this fork also provides:
- Updated API to make use of Java 8
- Major Bug fixes
- Independent client configuration
- Improved API
- Updated async requests to use Java 8 CompletableFuture
- Lazy response body parsing
- Default json mapper with Gson
<dependency>
<groupId>io.joshworks.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.6.0</version>
</dependency>
Please read the Unirest Documentation for basic examples on how to use the core api. This documentation aims to show the additional features and improvements from the original library.
The following example creates a new basic RestClient instance. At the moment, each client will have its own HttpClient sync and async client.
RestClient client = RestClient.newClient().build();
RestClient client = RestClient.newClient().baseUrl("http://my-api.com/v1").build();
String response = client.get("/some-resource").asString();
Unirest provides the same static methods as the original version. It's ideal for simple usage with default configuration.
String response = Unirest.get("http://my-api.com/v1").asString();
When using asynchronous requests you can use Java 8 CompletableFuture to handle the response. This also gives you the ability to compose multiple requests in a convenient way.
client.get("http://my-api.com/v1/hello")
.asStringAsync()
.thenAccept(resp -> {
System.out.println(resp.getBody())
})
.exceptionally(e -> {
e.printStackTrace();
return null;
});
The new API for form data makes easier to specify the right values for each type of request. When using .part(...)
a
multipart/form-data
request will be sent, .field(...)
will create x-www-form-urlencoded
request. This makes the interface cleaner and less error prone.
The content type is also set automatically.
//multipart
client.post("http://my-service.com/fileUpload")
.part("param3", value)
.part("file", new File("test.txt"))
.asJson();
//form-urlencoded
client.post("http://my-service.com/login")
.field("username", "admin")
.field("password", "admin123")
.asJson();
Before using asObject(Class)
or .body(Object)
, is necessary to provide a custom implementation of the ObjectMapper
interface.
This should be done for each client.
By default Gson is used as the default serializer, so there's no need to register any other json mapper unless you want a custom configuration.
Here's how to configure a new ObjectMapper:
public class XmlMapper implements ObjectMapper {
@Override
public <T> T readValue(String value, Class<T> valueType) {
//...
}
@Override
public String writeValue(Object value) {
//...
}
}
ObjectMappers.register(MediaType.APPLICATION_XML_TYPE, new XmlMapper());
HttpResponse<User> response = client.post("http://my-api.com/echo-xml")
.header("Accept", "application/xml")
.header("Content-Type", "application/xml")
.body(new User("John"))
.asObject(User.class);
The API also exposes HttpClient's PoolStats, so you can inspect the usage of each client.
ClientStats stats = client.stats();
int leased = stats.sync.getLeased();
int available = stats.sync.getAvailable();
int max = stats.sync.getMax();
int pending = stats.sync.getPending();
//All clients
Map<String, ClientStats> allStats = ClientContainer.stats();
//...
RestClient starts a background idle thread monitor, which is a daemon thread.
When exiting the application, you can use the ClientContainer
to release all the allocated resources, as follows:
//If a client is no longer needed and you want to dispose its resources
client.shutdown();
//When your application is shutting down:
//Closes all client connections and the monitor
ClientContainer.shutdown();