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

net.dongliu.commons.request.Request Maven / Gradle / Ivy

package net.dongliu.commons.request;

import net.dongliu.commons.lang.Charsets;
import net.dongliu.commons.lang.collection.Pair;

import static net.dongliu.commons.lang.collection.Helper.*;

import net.dongliu.commons.request.code.BodyTransformer;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * construct and execute http request
 *
 * @param  the response Type
 * @author Dong Liu
 */
public class Request {
    private final HttpRequestBase request;
    private final BodyTransformer transformer;
    private final RequestConfig config;
    private final CredentialsProvider provider;
    private final boolean gzip;
    private final boolean checkSsl;

    private Request(HttpRequestBase request, RequestConfig config, BodyTransformer transformer,
                    CredentialsProvider provider, boolean gzip, boolean checkSsl) {
        this.request = request;
        this.config = config;
        this.transformer = transformer;
        this.provider = provider;
        this.gzip = gzip;
        this.checkSsl = checkSsl;
    }

    public Response execute() {
        request.setConfig(config);
        if (gzip) {
            request.addHeader(Header.Accept_Encoding, Header.Accept_Encoding_COMPRESS);
        }

        HttpClientBuilder clientBuilder = HttpClients.custom();
        if (provider != null) {
            clientBuilder.setDefaultCredentialsProvider(provider);
        }
        if (!checkSsl) {
            SSLConnectionSocketFactory sslsf;
            try {
                SSLContextBuilder builder = new SSLContextBuilder();
                builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
                sslsf = new SSLConnectionSocketFactory(builder.build());
            } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
                throw new RuntimeException(e);
            }
            clientBuilder.setSSLSocketFactory(sslsf);
        }

        try (CloseableHttpClient client = clientBuilder.build()) {
            try (CloseableHttpResponse httpResponse = client.execute(request)) {
                Response response = new Response<>();
                response.setCode(httpResponse.getStatusLine().getStatusCode());
                List> headers = Arrays.stream(httpResponse.getAllHeaders())
                        .map(h -> pair(h.getName(), h.getValue()))
                        .collect(Collectors.toList());
                response.setHeaders(headers);
                T result = transformer.fromBody(httpResponse.getEntity());
                response.setBody(result);
                return response;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * get one request client for return result with Type T.
     */
    public static  Builder client(BodyTransformer transformer) {
        return new Builder().transformer(transformer);
    }

    /**
     * get one request client for return string result.
     */
    public static Builder stringRespClient() {
        return client(BodyTransformer.string);
    }

    /**
     * get one request client for return byte array result.
     */
    public static Builder bytesRespClient() {
        return client(BodyTransformer.bytes);
    }

    public static class Builder {
        private Method method;
        private String url;
        private byte[] body;
        private List params = new ArrayList<>();
        private List
headers = new ArrayList<>(); private BodyTransformer transformer; private RequestConfig.Builder configBuilder = RequestConfig.custom() .setConnectTimeout(10_000).setSocketTimeout(10_000); private CredentialsProvider provider; private boolean gzip; private boolean checkSsl = true; private Builder() { } public Request build() { HttpRequestBase request; switch (method) { case POST: request = getHttpPost(); break; case GET: request = getHttpGet(); break; case HEAD: case PUT: case DELETE: default: //TODO: put/delete throw new UnsupportedOperationException(); } headers.forEach(h -> request.addHeader(h.getName(), h.valueAsString())); return new Request<>(request, configBuilder.build(), transformer, provider, gzip, checkSsl); } private HttpPost getHttpPost() { if (!params.isEmpty() && body != null) { throw new IllegalArgumentException("Post body and params cannot set both"); } HttpPost httpPost = new HttpPost(url); if (!params.isEmpty()) { List paramList = this.params.stream() .map((e) -> new BasicNameValuePair(e.getName(), e.valueAsString())) .collect(Collectors.toList()); UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, Charsets.UTF_8); addHeader(Header.CONTENT_TYPE, Header.CONTENT_TYPE_FORM); httpPost.setEntity(entity); } else if (body != null) { httpPost.setEntity(new ByteArrayEntity(body)); } return httpPost; } private HttpRequestBase getHttpGet() { HttpRequestBase request; URI uri; try { uri = new URI(url); } catch (URISyntaxException e) { throw new RuntimeException(e); } URIBuilder urlBuilder = new URIBuilder(uri); this.params.stream().forEach(e -> urlBuilder.addParameter(e.getName(), e.valueAsString())); try { uri = urlBuilder.build(); } catch (URISyntaxException e) { throw new RuntimeException(e); } request = new HttpGet(uri); return request; } private Builder url(String url) { this.url = url; return this; } /** * get url, and return content */ public Response get(String url) { return method(Method.GET).url(url).build().execute(); } /** * post, and return content */ public Response post(String url) { return method(Method.POST).url(url).build().execute(); } public Response put(String url) { return method(Method.PUT).url(url).build().execute(); } public Response delete(String url) { return method(Method.DELETE).url(url).build().execute(); } /** * set userAgent */ public Builder userAgent(String userAgent) { if (userAgent != null) { addHeader("User-Agent", userAgent); } return this; } /** * add parameters */ public Builder addParams(Map params) { params.forEach(this::addParam); return this; } /** * add one parameter */ public Builder addParam(String key, Object value) { this.params.add(Parameter.of(key, value)); return this; } /** * set http body data for Post/Put requests * * @param body the data to post */ public Builder body(byte[] body) { this.body = body; return this; } /** * set http body with string */ public Builder body(String body, Charset charset) { return body(body.getBytes(charset)); } private Builder method(Method method) { this.method = method; return this; } /** * add headers */ public Builder addHeaders(Map params) { params.forEach(this::addHeader); return this; } /** * add header */ public Builder addHeader(String key, Object value) { this.headers.add(Header.of(key, value)); return this; } /** * set transformer. default is String transformer */ private Builder transformer(BodyTransformer transformer) { this.transformer = transformer; return this; } /** * set socket connect timeout in milliseconds. default is 10_000 */ public Builder connectTimeout(int timeout) { configBuilder.setConnectTimeout(timeout); return this; } /** * set socket read timeout in milliseconds. default is 10_000 */ public Builder socketTimeout(int timeout) { configBuilder.setSocketTimeout(timeout); return this; } /** * set http proxy, will ignore null parameter. examples: *
         *     http://127.0.0.1:7890/
         *     https://127.0.0.1:7890/
         *     http://username:[email protected]:7890/
         * 
*/ public Builder proxy(String proxy) { if (proxy == null) { return null; } URI uri; try { uri = new URI(proxy); } catch (URISyntaxException e) { throw new RuntimeException(e); } String userInfo = uri.getUserInfo(); if (userInfo != null) { String[] items = userInfo.split(":"); String userName = items[0]; String password = items[1]; CredentialsProvider provider = new BasicCredentialsProvider(); provider.setCredentials(new AuthScope(uri.getHost(), uri.getPort()), new UsernamePasswordCredentials(userName, password)); this.provider = provider; } HttpHost httpHost = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme()); configBuilder.setProxy(httpHost); return this; } /** * send gzip request. default false */ public Builder enableGzip() { this.gzip = true; return this; } /** * disable ssl check for https request */ public Builder disableSslVerify() { this.checkSsl = false; return this; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy