Skip to content

jsunsoftware/http-request

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

http-request

This lib is built on apache http client for sending rest requests.

Main purpose of the http-request, create simple rest client quickly, manage your response very simple and don't worry about Exceptions.

http-request Features: Building your HttpRequest requires no more than 5 minutes.
Used builder pattern to create HttpClient, HttpRequest.
HttpRequest wraps HttpClient inside and provide handy functions to manage.
HttpRequest is immutable (thread safe after build).
There are overloaded methods of request() for sending request.
All exceptions are wrapped:
If connection failure -> status code is a 503(SC_SERVICE_UNAVAILABLE), If deserialization of response body is failed -> status code is a 502(SC_BAD_GATEWAY).
After request can be provided the ResponseHandler instance to manipulate response data.
Supported:

  • converting response to the type which you want.
  • ignore response body if you interested in only status code.
  • converting from Json.
  • converting from Xml.
    Optimized performance.

Full API documentation is available here.

Note: HttpRequest objects are immutable and thread-safe, they can be reused after build the instance of HttpRequest.

Client builder

The ClientBuilder have been added to build CloseableHttpClient with some handy methods. You can also use the apache HttpClientBuilder .
If you build the CloseableHttpClient there are overridden values:

  • ResponseTimeout: 30000ms
  • ConnectTimeout: 10000ms
  • ConnectionRequestTimeout: 30000ms
  • connectionManager#setDefaultMaxPerRoute: 128
  • connectionManager#setMaxTotal: 128

Can be changed through Client builder. See the API documentation ClientBuilder

Note: the httpClientInstance of CloseableHttpClient must't be shared over HttpRequests. It is strong advice don't create CloseableHttpClient instance for any request.
build httpClient Example:
CloseableHttpClient httpClient=ClientBuilder.create().setMaxPoolSize(256).build();

How to use

Retrieve the Status Code from the Http Response

After sending the Http request – we get back an instance of com.jsunsoft.http.Response –
which allows us to access the status line of the response, and implicitly the Status Code:

class Demo {
    private final HttpRequest httpRequest = HttpRequestBuilder.create(httpClient).build();

    void request() {
        Response response = httpRequest.target("https://www.jsunsoft.com/").get();
        int statusCode = response.getCode();
    }
}

Perform simple http request

Convert response body to Java class by some type you must build it so:

Using eager converting -> the response handler:

ResponseHandler<SomeType> rh = httpRequest.target(uri).path(path).request(HttpMethod.GET,SomeType.class);
SomeType someType = rh.get(); //see javadoc of get method
//or
SomeType someType = rh.orElseThrow(); //throws UnexpectedStatusCodeException If response code is not success

Using lazy converting -> the Response's readEntity:

Response r=httpRequest.target(uri).path(path).request(HttpMethod.GET,payload);
SomeType someType = r.readEntity(SomeType.class); //see javadoc of get method

Convert response body to Generic class (example List) by some type you must build it so:

Using eager converting -> the response handler:

ResponseHandler<SomeType> rh = httpRequest.target(uri).path(path).request(HttpMethod.POST,new TypeReference<List<SomeType>>(){});
List<SomeType> someTypes = rh.get(); //see javadoc of get method
//or
List<SomeType> someTypes = rh.orElse(Collections.emptyList()); //returns defaultValue value to return if content isn't present

Using lazy converting -> the Response's readEntity:

ResponseHandler<SomeType> rh=httpRequest.target(uri).path(path).request(HttpMethod.POST,payload);
List<SomeType> someTypes = r.readEntity(new TypeReference<List<SomeType>>(){}); //see javadoc of get method
You can use overridden methods instead of method request()

Do the same as above example.

ResponseHandler<SomeType> rh=httpRequest.target(uri).path(path).get(SomeType.class);
SomeType someType = rh.get(); 
Response r=httpRequest.target(uri).path(path).get();
SomeType someType = r.readEntity(SomeType.class); 
Note: If the SomeType contains dates default deserialization patterns are - LocalTime -> HH:mm:ss, LocalDate -> dd/MM/yyyy, LocalDateTime -> dd/MM/yyyy HH:mm:ss
It can be overridden by HttpRequestBuilder#addDefaultDateDeserializationPattern

Perform http request read response as String

ResponseHandler<String> rh=httpRequest.target(uri).path(path).post(payload);
String response = rh.get(); 
ResponseHandler<String> r=httpRequest.target(uri).path(path).post(payload);
String response = r.readEntity(String.class);

Perform http get request with parameters

ResponseHandler<SomeType> rh=httpRequest.target(uri)
        .path(path)
        .addParameter(name,value)
        .addParameter(new NameValuePair(name,value))
        .addParameters(queryString) //queryString example "param1=param1&param2=param2"
        .get(HttpMethod.GET,SomeType.class);

int statusCode = rh.getCode();
SomeType someType = rh.get();
//or
SomeType someType = rh.orElseThrow(); 

Get the Response and do manipulation yourself:

Response response=httpRequest.target(uri)
        .path(path)
        .addParameter(name,value)
        .addParameter(new NameValuePair(name,value))
        .addParameters(queryString) //queryString example "param1=param1&param2=param2"
        .get();

response.readEntity(SomeType.class)

Note: The Response is implementation of CloseableHttpResponse

Build HttpRequest and add HEADERS which should be send always through httpRequest

HttpRequest httpRequest=HttpRequestBuilder.create(httpClient)
        .addDefaultHeader(someHeader)
        .addDefaultHeaders(someHeaderCollection)
        .addDefaultHeaders(someHeaderArray)
        .addDefaultHeader(headerName,headerValue)
        .build()

Add custom body reader

import com.jsunsoft.http.*;

import java.util.Map;

class Demo {
  private final HttpRequest httpRequest = HttpRequestBuilder.create(closeableHttpClient)
          //.disableDefaultBodyReader() to disable default body reader even if custom is not readable in case if default body reader enabled but custom body reader exists and is readable the custom reader will be chosen.
          .addBodyReader(new ResponseBodyReader<Map<String, String>>() {
            @Override
            public boolean isReadable(ResponseBodyReadableContext bodyReadableContext) {
              return bodyReadableContext.getType() == Map.class;
            }

            @Override
            public ResponseData read(ResponseBodyReaderContext<SomeType> bodyReaderContext) throws IOException, ResponseBodyReaderException {
              return new ObjectMapper()
                      .disable(FAIL_ON_UNKNOWN_PROPERTIES)
                      .readValue(bodyReaderContext.getContent(), bodyReaderContext.getGenericType());
            }
          })
          .build();

  void request() {
    Response response = httpRequest.target("https://www.jsunsoft.com/").get();
    int statusCode = response.getCode();
    Map<String, String> responseMap = response.readEntity(new TypeReference<Map<String, String>>() {});
  }
}

Configure connection pool

By default connection pool size of apache http client is 2. When httpClient is built by ClientBuilder the default value changed to 128. To set custom value you can:

CloseableHttpClient httpClient=ClientBuilder.create()
        .setMaxPoolSize(256)
        .setDefaultMaxPoolSizePerRoute(200)
        .setMaxPoolSizePerRoute(host,56)
        .build()

How to set proxy

CloseableHttpClient httpClient=ClientBuilder.create().proxy(host,port).build();

Default request Timeouts

socketTimeOut is 30000ms
connectionRequestTimeout is 30000ms
connectTimeout is 5000ms;

For more information see (https://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html) or (http://www.baeldung.com/httpclient-timeout)

To change default timeouts you can:

CloseableHttpClient httpClient=ClientBuilder.create()
        .setConnectTimeout(intValue)
        .setSocketTimeOut(intValue)
        .setConnectionRequestTimeout(intValue)
        .build();

Timeouts can be overridden for each request:

HttpRequest httpRequest=HttpRequestBuilder.create(httpClient).build();

        httpRequest.target(uri).setRequestConfig(customReequestConfig).get();

Following redirects

By default redirecting are disabled. to enable you can:

CloseableHttpClient httpClient=ClientBuilder.create().enableLaxRedirectStrategy().build();
        or
        CloseableHttpClient httpClient=ClientBuilder.create().enableDefaultRedirectStrategy().build();
        or set custom redirect strategy
        CloseableHttpClient httpClient=ClientBuilder.create().setRedirectStrategy(yourRedirectStrategyInstance).build();

Ignore SSL certificate

CloseableHttpClient httpClient=ClientBuilder.create()
        .trustAllCertificates()
        .trustAllHosts()
        .build();

        int statusCode=httpRequest.target("https://mms.nw.ru/")
        .addHeader("accept","application/json")
        .get().getCode(); // 200

Basic Authentication

HttpRequest httpRequest=HttpRequestBuilder.create(httpClient)
        .basicAuth("username_admin","secret_password").build();

        int statusCode=httpRequest.get().getCode(); //200

Customize CloseableHttpClient before the http-request is built

ClietBuilder.create()
        .addHttpClientCustomizer(httpClientBuilder-> /* here you can customize your client*/)
        .build();

For example if you want to add the Keep-Alive:

ClietBuilder.create()
        .addHttpClientCustomizer(httpClientBuilder->httpClientBuilder.setKeepAliveStrategy((response,context)->{
        //your code;
        }))
        .build();

Real world example how http-request simple and useful.

No try/catch, No if/else

import com.jsunsoft.http.ClientBuilder;
import com.jsunsoft.http.ResponseHandler;
import com.jsunsoft.http.TypeReference;
import org.apache.hc.core5.http.ContentType;

import java.util.List;


public class Rest {

  private static final HttpRequest httpRequest =
          HttpRequestBuilder.create(ClientBuilder.create().build())
                  .addContentType(ContentType.APPLICATION_JSON)
                  .build();

  public void send(String jsonData) {
    httpRequest.target("https://www.jsunsoft.com/").get(jsonData, new TypeReference<List<String>>() {})
            .ifSuccess(this::whenSuccess) //call whenSuccess method if request is success
            .otherwise(this::whenNotSuccess); //call whenNotSuccess method if request is success
  }

  private void whenSuccess(ResponseHandler<List<String>> responseHandler) {
    //When predicate of filter returns true, calls whenHasContent else calls whenHasNotContent
    responseHandler.filter(ResponseHandler::hasContent) //if request has content will be executed ifPassed consumer else otherwise consumer
            .ifPassed(this::whenHasContent)  //call hasContent method if request body is present
            .otherwise(this::whenHasNotContent);
  }

  private void whenNotSuccess(ResponseHandler<List<String>> responseHandler) {
    //For demo. You can handle what you want
    System.err.println("Error code: " + responseHandler.getCode() + ", error message: " + responseHandler.getErrorText());
  }

  private void whenHasContent(ResponseHandler<List<String>> responseHandler) {
    //For demo. 
    List<String> responseBody = responseHandler.get();
    System.out.println(responseBody);
  }

  private void whenHasNotContent(ResponseHandler<List<String>> responseHandler) {
    //For demo. 
    System.out.println("Response is success but body is missing. Response code: " + responseHandler.getCode());
  }
}

To use from maven add this snippet to the pom.xml dependencies section:

<dependency>
    <groupId>com.jsunsoft.http</groupId>
  <artifactId>http-request</artifactId>
  <version>3.2.1</version>
</dependency>

Pull requests are welcome.

Supported by https://www.jetbrains.com/?from=http-request