All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.seppiko.commons.utils.http.HttpClientUtil Maven / Gradle / Ivy

There is a newer version: 2.11.0
Show newest version
/*
 * Copyright 2023 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.seppiko.commons.utils.http;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.time.Duration;
import java.util.Map;
import java.util.Objects;
import javax.net.ssl.SSLContext;

/**
 * Http Client Util with java.net.http
 *
 * @author Leonard Woo
 */
public class HttpClientUtil {

  HttpClientUtil() {}

  /**
   * Get Request instance with String
   *
   * @param url URL String.
   * @param method see {@link HttpMethod}.
   * @param timeout Timeout.
   * @param headers see {@link HttpHeaders}.
   * @param requestBody Request body string.
   * @return HttpRequest instance.
   * @throws URISyntaxException URL is an illegal address.
   * @throws IllegalArgumentException something not supported or undefined.
   * @throws NullPointerException something is {@code null}.
   * @throws HttpRuntimeException Http request process exception.
   */
  public static HttpRequest getRequest(
      String url, HttpMethod method, int timeout, HttpHeaders headers, String requestBody)
      throws URISyntaxException, IllegalArgumentException, NullPointerException,
          HttpRuntimeException {

    if (Objects.isNull(headers)) {
      headers = HttpHeaders.newHeaders();
    }

    HttpRequest.BodyPublisher requestBodyPublisher =
        Objects.nonNull(requestBody)
            ? HttpRequest.BodyPublishers.ofString(requestBody)
            : HttpRequest.BodyPublishers.noBody();

    return getRequestRaw(
        new URI(url), method, timeout, headers.getHeaderMap(), requestBodyPublisher);
  }

  /**
   * Get Request instance with InputStream
   *
   * @param url URL String.
   * @param method see {@link HttpMethod}.
   * @param timeout Timeout.
   * @param headers see {@link HttpHeaders}.
   * @param requestBody Request body input stream.
   * @return HttpRequest instance.
   * @throws URISyntaxException URL is an illegal address.
   * @throws IllegalArgumentException something not supported or undefined.
   * @throws NullPointerException something is {@code null}.
   * @throws HttpRuntimeException Http request process exception.
   */
  public static HttpRequest getRequest(
      String url, HttpMethod method, int timeout, HttpHeaders headers, InputStream requestBody)
      throws URISyntaxException, IllegalArgumentException, NullPointerException,
          HttpRuntimeException {

    if (Objects.isNull(headers)) {
      headers = HttpHeaders.newHeaders();
    }

    HttpRequest.BodyPublisher requestBodyPublisher =
        Objects.nonNull(requestBody)
            ? HttpRequest.BodyPublishers.ofInputStream(() -> requestBody)
            : HttpRequest.BodyPublishers.noBody();

    return getRequestRaw(
        new URI(url), method, timeout, headers.getHeaderMap(), requestBodyPublisher);
  }

  /**
   * Get Request instance with byte array
   *
   * @param url URL String.
   * @param method see {@link HttpMethod}.
   * @param timeout Timeout.
   * @param headers see {@link HttpHeaders}.
   * @param requestBody Request body byte array.
   * @return HttpRequest instance.
   * @throws URISyntaxException URL is an illegal address.
   * @throws IllegalArgumentException something not supported or undefined.
   * @throws NullPointerException something is {@code null}.
   * @throws HttpRuntimeException Http request process exception.
   */
  public static HttpRequest getRequest(
      String url, HttpMethod method, int timeout, HttpHeaders headers, byte[] requestBody)
      throws URISyntaxException, IllegalArgumentException, NullPointerException,
          HttpRuntimeException {

    if (Objects.isNull(headers)) {
      headers = HttpHeaders.newHeaders();
    }

    HttpRequest.BodyPublisher requestBodyPublisher =
        Objects.nonNull(requestBody)
            ? HttpRequest.BodyPublishers.ofByteArray(requestBody)
            : HttpRequest.BodyPublishers.noBody();

    return getRequestRaw(
        new URI(url), method, timeout, headers.getHeaderMap(), requestBodyPublisher);
  }

  /**
   * Get Response instance with String body
   *
   * @param req HttpRequest instance.
   * @param sslContext HTTP TLS Context, if unused set {@link TLSUtil#NULL_SSL_CONTEXT}. see {@link TLSUtil}.
   * @param proxy Http proxy, Not {@code null} is enabled proxy.
   * @return HttpResponse object, if NULL has failed.
   * @throws HttpClientException get response exception.
   * @throws HttpInterruptedException if the operation is interrupted
   */
  public static HttpResponse getResponseString(
      HttpRequest req, SSLContext sslContext, InetSocketAddress proxy)
      throws HttpClientException, HttpInterruptedException {
    return getResponseRaw(req, BodyHandlers.ofString(), sslContext, proxy);
  }

  /**
   * Get Response instance with byte array body
   *
   * @param req HttpRequest instance.
   * @param sslContext HTTP TLS Context, if unused set {@link TLSUtil#NULL_SSL_CONTEXT}. see {@link TLSUtil}.
   * @param proxy Http proxy, Not {@code null} is enabled proxy.
   * @return HttpResponse object, if NULL has failed.
   * @throws HttpClientException get response exception.
   * @throws HttpInterruptedException if the operation is interrupted.
   */
  public static HttpResponse getResponseByteArray(
      HttpRequest req, SSLContext sslContext, InetSocketAddress proxy)
      throws HttpClientException, HttpInterruptedException {
    return getResponseRaw(req, BodyHandlers.ofByteArray(), sslContext, proxy);
  }

  /**
   * Get Response instance with InputStream body
   *
   * @param req HttpRequest instance.
   * @param sslContext HTTP TLS Context, if unused set {@link TLSUtil#NULL_SSL_CONTEXT}. see {@link TLSUtil}.
   * @param proxy Http proxy, Not {@code null} is enabled proxy.
   * @return HttpResponse object, if NULL has failed.
   * @throws HttpClientException get response exception.
   * @throws HttpInterruptedException if the operation is interrupted.
   */
  public static HttpResponse getResponseInputStream(
      HttpRequest req, SSLContext sslContext, InetSocketAddress proxy)
      throws HttpClientException, HttpInterruptedException {
    return getResponseRaw(req, BodyHandlers.ofInputStream(), sslContext, proxy);
  }

  /**
   * Get HTTP request raw
   *
   * @param uri request uri string.
   * @param method request method, see {@link HttpMethod}.
   * @param timeout request timeout.
   * @param headers request headers, see {@link HttpHeaders}, if none is {@code null}.
   * @param requestBody request body.
   * @return HttpRequest object
   * @throws IllegalArgumentException URI method or headers is not support or valid
   * @throws IllegalStateException if a URI has not been set
   * @throws HttpTimeoutException timeout is not valid
   */
  protected static HttpRequest getRequestRaw(
      URI uri, HttpMethod method, int timeout, Map headers,
      HttpRequest.BodyPublisher requestBody)
      throws IllegalArgumentException, IllegalStateException, HttpTimeoutException {
    HttpRequest.Builder builder =
        HttpRequest.newBuilder().uri(uri).method(method.name(), requestBody);
    if (!headers.isEmpty()) {
      headers.forEach(builder::header);
    }
    try {
      builder = builder.timeout(Duration.ofSeconds(timeout));
    } catch (IllegalArgumentException ex) {
      throw new HttpTimeoutException("HTTP request timeout.");
    }
    return builder.build();
  }

  /**
   * Get HTTP response raw
   *
   * @param req HTTP request
   * @param responseBodyHandler Response body content type.
   * @param sslContext HTTP TLS Context, if unused set {@link TLSUtil#NULL_SSL_CONTEXT}. see {@link TLSUtil}.
   * @param proxy HTTP Proxy, Not null is enabled proxy.
   * @return Http response instance.
   * @param  Response content type.
   * @throws HttpInterruptedException If the response is interrupted.
   * @throws HttpResponseException If the response has I/O error or not valid.
   * @throws SecurityException If a security manager has been installed, and it denies access to the
   *     URL in the given request, or proxy if one is configured.
   */
  protected static  HttpResponse getResponseRaw(
      HttpRequest req, HttpResponse.BodyHandler responseBodyHandler, SSLContext sslContext, InetSocketAddress proxy)
      throws HttpInterruptedException, HttpResponseException, SecurityException {
    try {
      HttpClient.Builder builder = HttpClient.newBuilder();
      if (Objects.nonNull(proxy)) {
        builder = builder.proxy(ProxySelector.of(proxy));
      }
      if (sslContext != TLSUtil.NULL_SSL_CONTEXT) {
        builder = builder.sslContext(sslContext);
      }
      return builder.build().send(req, responseBodyHandler);
    } catch (InterruptedException ex) {
      throw new HttpInterruptedException(ex);
    } catch (IOException | IllegalArgumentException ex) {
      throw new HttpResponseException(ex);
    }
  }

  /**
   * Request body checker
   *
   * @param requestBody request body.
   * @return BodyPublisher instance.
   * @param  body type.
   * @throws UnsupportedOperationException not found request body class type
   */
  protected static  HttpRequest.BodyPublisher getBodyPublisher(T requestBody)
      throws UnsupportedOperationException {
    if (Objects.isNull(requestBody)) {
      return HttpRequest.BodyPublishers.noBody();
    }
    Class type = requestBody.getClass();
    if (type.isAssignableFrom(CharSequence.class)) {
      return HttpRequest.BodyPublishers.ofString(requestBody.toString());
    }
    if (type.isAssignableFrom(InputStream.class)) {
      return HttpRequest.BodyPublishers.ofInputStream(() -> (InputStream) requestBody);
    }
    if (requestBody instanceof byte[]) {
      return HttpRequest.BodyPublishers.ofByteArray((byte[]) requestBody);
    }
    throw new UnsupportedOperationException("Can NOT found supported type");
  }

  /**
   * Response body checker
   *
   * @param type response type.
   * @return BodyHandler instance.
   * @param  class type.
   */
  protected static  HttpResponse.BodyHandler getBodyHandler(Class type) {
    if (type == null || type.isAssignableFrom(String.class)) {
      return BodyHandlers.ofString();
    }
    if (type.isAssignableFrom(InputStream.class)) {
      return BodyHandlers.ofInputStream();
    }
    return BodyHandlers.ofByteArray();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy