io.joshworks.restclient.http.ClientRequest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of unirest-java Show documentation
Show all versions of unirest-java Show documentation
Rest Java client based on Unirest
package io.joshworks.restclient.http;
import io.joshworks.restclient.Constants;
import io.joshworks.restclient.http.async.Callback;
import io.joshworks.restclient.http.exceptions.RestClientException;
import io.joshworks.restclient.request.HttpRequest;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.nio.entity.NByteArrayEntity;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* Created by Josh Gontijo on 5/3/17.
*/
public class ClientRequest {
private final CloseableHttpClient syncClient;
private final CloseableHttpAsyncClient asyncClient;
private final Map defaultHeaders;
public final String url;
public final HttpMethod httpMethod;
ClientRequest(HttpMethod httpMethod, String url, CloseableHttpClient syncClient, CloseableHttpAsyncClient asyncClient, Map defaultHeaders) {
this.url = url;
this.httpMethod = httpMethod;
this.syncClient = syncClient;
this.asyncClient = asyncClient;
this.defaultHeaders = defaultHeaders;
}
private static final String USER_AGENT = "rest-client/1.6.0";
private FutureCallback prepareCallback(
final Class responseClass,
final Callback callback) {
if (callback == null)
return null;
return new FutureCallback() {
public void cancelled() {
callback.cancelled();
}
public void completed(org.apache.http.HttpResponse arg0) {
callback.completed(new HttpResponse<>(arg0, responseClass));
}
public void failed(Exception arg0) {
callback.failed(arg0);
}
};
}
public CompletableFuture> requestAsync(HttpRequest request, final Class responseClass) {
HttpUriRequest requestObj = prepareRequest(request, true);
if (asyncClient == null) {
throw new RestClientException("Async client not configured");
}
if (!asyncClient.isRunning()) {
asyncClient.start();
}
CompletableFuture> completableFuture = new CompletableFuture<>();
asyncClient.execute(requestObj, prepareCallback(responseClass, new Callback() {
@Override
public void completed(HttpResponse response) {
completableFuture.complete(response);
}
@Override
public void failed(Exception e) {
completableFuture.completeExceptionally(e);
}
@Override
public void cancelled() {
//do nothing
}
}));
return completableFuture;
}
public Future> requestAsync(
HttpRequest request,
final Class responseClass,
Callback callback) {
HttpUriRequest requestObj = prepareRequest(request, true);
if (asyncClient == null) {
throw new RestClientException("Async client not configured");
}
if (!asyncClient.isRunning()) {
asyncClient.start();
}
final Future future = asyncClient.execute(requestObj, prepareCallback(responseClass, callback));
return new Future>() {
public boolean cancel(boolean mayInterruptIfRunning) {
return future.cancel(mayInterruptIfRunning);
}
public boolean isCancelled() {
return future.isCancelled();
}
public boolean isDone() {
return future.isDone();
}
public HttpResponse get() throws InterruptedException, ExecutionException {
return this.getResponse();
}
public HttpResponse get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return this.getResponse(timeout, unit);
}
private HttpResponse getResponse() throws ExecutionException, InterruptedException {
org.apache.http.HttpResponse httpResponse = future.get();
return new HttpResponse<>(httpResponse, responseClass);
}
private HttpResponse getResponse(long timeout, TimeUnit unit) throws ExecutionException, InterruptedException, TimeoutException {
org.apache.http.HttpResponse httpResponse = future.get(timeout, unit);
return new HttpResponse<>(httpResponse, responseClass);
}
};
}
public HttpResponse request(final HttpRequest request, final Class responseClass) {
if (syncClient == null) {
throw new RestClientException("Sync client not configured");
}
HttpRequestBase requestObj = prepareRequest(request, false);
org.apache.http.HttpResponse response;
try {
response = syncClient.execute(requestObj);
return HttpResponse.create(requestObj, response, responseClass);
} catch (Exception e) {
throw new RestClientException(e);
}
}
private HttpRequestBase prepareRequest(HttpRequest request, boolean async) {
if (defaultHeaders != null) {
for (Map.Entry entry : defaultHeaders.entrySet()) {
//Do not set content-type for multipart and urlencoded
if (!entry.getKey().equalsIgnoreCase(HttpHeaders.CONTENT_TYPE) || request.getBody() == null || !request.getBody().implicitContentType()) {
request.header(entry.getKey(), String.valueOf(entry.getValue()));
}
}
}
if (!request.getHeaders().containsKey(HttpHeaders.USER_AGENT)) {
request.header(HttpHeaders.USER_AGENT, USER_AGENT);
}
if (!request.getHeaders().containsKey(HttpHeaders.ACCEPT_ENCODING)) {
request.header(HttpHeaders.ACCEPT_ENCODING, Constants.GZIP);
}
String urlToRequest;
try {
URL reqUrl = new URL(request.getUrl());
URI uri = new URI(reqUrl.getProtocol(), reqUrl.getUserInfo(), reqUrl.getHost(), reqUrl.getPort(), URLDecoder.decode(reqUrl.getPath(), Constants.UTF_8), "", reqUrl.getRef());
urlToRequest = uri.toURL().toString();
if (reqUrl.getQuery() != null && !reqUrl.getQuery().trim().equals("")) {
if (!urlToRequest.substring(urlToRequest.length() - 1).equals(Constants.QUESTION_MARK)) {
urlToRequest += Constants.QUESTION_MARK;
}
urlToRequest += reqUrl.getQuery();
} else if (urlToRequest.substring(urlToRequest.length() - 1).equals(Constants.QUESTION_MARK)) {
urlToRequest = urlToRequest.substring(0, urlToRequest.length() - 1);
}
} catch (Exception e) {
throw new RestClientException(e);
}
HttpRequestBase reqObj = null;
switch (request.getHttpMethod()) {
case GET:
reqObj = new HttpGet(urlToRequest);
break;
case POST:
reqObj = new HttpPost(urlToRequest);
break;
case PUT:
reqObj = new HttpPut(urlToRequest);
break;
case DELETE:
reqObj = new HttpDeleteWithBody(urlToRequest);
break;
case PATCH:
reqObj = new HttpPatchWithBody(urlToRequest);
break;
case OPTIONS:
reqObj = new HttpOptionsWithBody(urlToRequest);
break;
case HEAD:
reqObj = new HttpHead(urlToRequest);
break;
default:
throw new IllegalArgumentException("Invalid HTTP method: " + request.getHttpMethod());
}
for (Map.Entry> entry : request.getHeaders().entrySet()) {
List values = entry.getValue();
if (values != null) {
for (String value : values) {
reqObj.addHeader(entry.getKey(), value);
}
}
}
// Set body
if (request.getHttpMethod() != HttpMethod.GET && request.getHttpMethod() != HttpMethod.HEAD) {
if (request.getBody() != null) {
HttpEntity entity = request.getBody().getEntity();
if (async) {
if (reqObj.getHeaders(HttpHeaders.CONTENT_TYPE) == null || reqObj.getHeaders(HttpHeaders.CONTENT_TYPE).length == 0) {
reqObj.setHeader(entity.getContentType());
}
try {
ByteArrayOutputStream output = new ByteArrayOutputStream();
entity.writeTo(output);
NByteArrayEntity en = new NByteArrayEntity(output.toByteArray());
((HttpEntityEnclosingRequestBase) reqObj).setEntity(en);
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
((HttpEntityEnclosingRequestBase) reqObj).setEntity(entity);
}
}
}
return reqObj;
}
}