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

com.feingto.cloud.kit.http.ApacheHttpClient Maven / Gradle / Ivy

There is a newer version: 2.5.2.RELEASE
Show newest version
package com.feingto.cloud.kit.http;

import lombok.Data;
import lombok.SneakyThrows;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.util.StreamUtils;

import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Apache Http Fluent 客户端
 *
 * @author longfei
 */
@Slf4j
@Data
@Accessors(fluent = true)
public class ApacheHttpClient {
    private static final Integer DEFAULT_REQUEST_TIMEOUT = 30;
    private HttpMethod method = HttpMethod.GET;
    private Map headers = new HashMap<>();
    /**
     * 超时秒数, 默认60秒
     */
    private int timeout = DEFAULT_REQUEST_TIMEOUT;
    /**
     * 重试次数
     */
    private int retry = 0;

    public ClientResponse invoke(String url) {
        return this.invoke(url, new HashMap<>());
    }

    public ClientResponse invoke(String url, Map params) {
        Request request;
        switch (this.method) {
            case GET:
                return this.invoke(Request.Get(this.buildUri(url, params)));
            case POST:
                request = Request.Post(url);
                if (MapUtils.isNotEmpty(params)) {
                    request.bodyForm(this.buildFormParams(params), StandardCharsets.UTF_8);
                }
                return this.invoke(request);
            case PUT:
                request = Request.Put(url);
                if (MapUtils.isNotEmpty(params)) {
                    request.bodyForm(this.buildFormParams(params), StandardCharsets.UTF_8);
                }
                return this.invoke(request);
            case DELETE:
                return this.invoke(Request.Delete(this.buildUri(url, params)));
        }
        return ClientResponse.badRequest();
    }

    public ClientResponse invoke(String url, byte[] bytes, ContentType contentType) {
        if (HttpMethod.POST == this.method) {
            Request request = Request.Post(url).bodyByteArray(bytes, contentType.withCharset(StandardCharsets.UTF_8));
            return this.invoke(request);
        }
        if (HttpMethod.PUT == this.method) {
            Request request = Request.Put(url).bodyByteArray(bytes, contentType.withCharset(StandardCharsets.UTF_8));
            return this.invoke(request);
        }
        return ClientResponse.badRequest();
    }

    public ClientResponse invoke(String url, InputStream inputStream) {
        if (HttpMethod.POST == this.method) {
            return this.invoke(Request.Post(url), inputStream);
        }
        if (HttpMethod.PUT == this.method) {
            return this.invoke(Request.Put(url), inputStream);
        }
        return ClientResponse.badRequest();
    }

    private ClientResponse invoke(Request request, InputStream inputStream) {
        request = request.bodyStream(inputStream, ContentType.MULTIPART_FORM_DATA.withCharset(StandardCharsets.UTF_8));
        return this.invoke(request);
    }

    private ClientResponse invoke(Request request) {
        request.connectTimeout(timeout * 1000).socketTimeout(timeout * 1000).useExpectContinue();
        if (MapUtils.isNotEmpty(headers)) {
            headers.forEach(request::addHeader);
        }
        try {
            org.apache.http.HttpResponse response = request.execute().returnResponse();
            HttpHeaders httpHeaders = new HttpHeaders();
            Arrays.stream(response.getAllHeaders()).forEach(it -> httpHeaders.add(it.getName(), it.getValue()));
            return new ClientResponse()
                    .setStatusCode(response.getStatusLine().getStatusCode())
                    .setBody(Objects.nonNull(response.getEntity()) ? response.getEntity().getContent() : StreamUtils.emptyInput())
                    .setHeaders(httpHeaders)
                    .setSuccessful(response.getStatusLine().getStatusCode() == HttpStatus.OK.value());
        } catch (Exception e) {
            if (retry > 0) {
                log.debug("The request failed and retried {} times", retry);
                retry -= 1;
                this.invoke(request);
            }
            log.error("Request internal error: invalid service url", e);
            return Optional.of(e)
                    .filter(it -> it instanceof SocketTimeoutException)
                    .map(it -> ClientResponse.requestTimeout())
                    .orElse(ClientResponse.error("Request internal error: invalid service url"));
        }
    }

    private Iterable buildFormParams(Map params) {
        return params.keySet().stream()
                .map(key -> new BasicNameValuePair(key, params.get(key)))
                .collect(Collectors.toList());
    }

    @SneakyThrows
    private URI buildUri(String url, Map params) {
        URIBuilder uri = new URIBuilder(url);
        if (MapUtils.isNotEmpty(params)) {
            params.forEach(uri::addParameter);
        }
        return uri.build();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy