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

shz.core.net.HttpClient Maven / Gradle / Ivy

There is a newer version: 2024.0.2
Show newest version
package shz.core.net;

import shz.core.*;
import shz.core.PRException;
import shz.core.id.IdHelp;
import shz.core.io.IOHelp;
import shz.core.msg.ClientFailureMsg;
import shz.core.reference.LReference;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

public final class HttpClient {
    private HttpClient() {
        throw new IllegalStateException();
    }

    //GET,POST,HEAD,OPTIONS,PUT,DELETE,TRACE;
    //PATCH,CONNECT;

    public static void connect(URL url, String method, Map headers, byte[] body, HttpRequestConfig config, Consumer consumer) {
        try {
            HttpURLConnection conn;
            if (config != null && NullHelp.nonBlank(config.getProxyHost()) && config.getProxyPort() > 0) {
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(config.getProxyHost(), config.getProxyPort()));
                conn = (HttpURLConnection) url.openConnection(proxy);
            } else conn = (HttpURLConnection) url.openConnection();

            if (config != null && conn instanceof HttpsURLConnection) {
                SSLContext sslContext = config.getSslContext();
                if (sslContext != null) ((HttpsURLConnection) conn).setSSLSocketFactory(sslContext.getSocketFactory());
            }

            conn.setRequestMethod(method);
            if (config != null) {
                conn.setDoInput(config.isDoInput());
                conn.setDoOutput(config.isDoOutput());
                conn.setIfModifiedSince(config.getIfModifiedSince());
                conn.setUseCaches(config.isUseCaches());
                conn.setAllowUserInteraction(config.isAllowUserInteraction());
                conn.setConnectTimeout(config.getConnectTimeoutMillis());
                conn.setReadTimeout(config.getReadTimeoutMillis());
                conn.setInstanceFollowRedirects(config.getRedirects() < 0);
            }

            if (NullHelp.nonEmpty(headers)) headers.forEach(conn::setRequestProperty);
            if (NullHelp.nonEmpty(body)) {
                conn.setDoOutput(true);
                conn.getOutputStream().write(body);
            }

            conn.connect();
            consumer.accept(conn);
        } catch (Exception e) {
            throw PRException.of(e);
        }
    }

    public static void connect(URL url, String method, Map headers, byte[] body, HttpRequestConfig config, BiConsumer consumer) {
        connect(url, method, headers, body, config, conn -> {
            IOException exc = null;
            int responseCode = -1;
            try {
                responseCode = conn.getResponseCode();
            } catch (IOException e) {
                exc = e;
            }

            if (config != null && !conn.getInstanceFollowRedirects()) {
                if (responseCode == HttpURLConnection.HTTP_MOVED_PERM
                        || responseCode == HttpURLConnection.HTTP_MOVED_TEMP
                        || responseCode == HttpURLConnection.HTTP_SEE_OTHER) {
                    String location = conn.getHeaderField("Location");
                    if (location != null) {
                        if (config.getRedirects() <= 0) throw new RuntimeException("Too many redirects!");
                        config.setRedirects(config.getRedirects() - 1);
                        URL base = conn.getURL();
                        conn.disconnect();
                        URL redirectUrl;
                        try {
                            redirectUrl = new URL(base, location);
                        } catch (MalformedURLException e) {
                            throw PRException.of(e);
                        }
                        connect(redirectUrl, method, headers, body, config, consumer);
                        return;
                    }
                }
            }

            InputStream is = null;
            if (exc != null) {
                is = conn.getErrorStream();
                if (is == null) throw PRException.of(exc);
            } else {
                try {
                    is = conn.getInputStream();
                } catch (IOException ignored) {
                }
            }
            if (is != null) {
                String contentEncoding = conn.getContentEncoding();
                consumer.accept(contentEncoding == null ? StandardCharsets.UTF_8 : Charset.forName(contentEncoding), is);
            }
        });
    }

    public static void connect(String url, String method, Map headers, byte[] body, HttpRequestConfig config, BiConsumer consumer) {
        URL u;
        try {
            u = new URL(url);
        } catch (MalformedURLException e) {
            throw PRException.of(e);
        }
        connect(u, method, headers, body, config, consumer);
    }

    public static String request(String url, String method, Map headers, byte[] body, HttpRequestConfig config) {
        LReference responseRef = new LReference<>();
        connect(url, method, headers, body, config, (charset, is) -> responseRef.set(IOHelp.read(IOHelp.newBufferedReader(is, charset))));
        return responseRef.get();
    }

    public static String get(String url, Map headers, HttpRequestConfig config) {
        return request(url, "GET", headers, null, config);
    }

    public static String get(String url, Map headers) {
        return get(url, headers, null);
    }

    public static String post(String url, Map headers, byte[] body, HttpRequestConfig config) {
        return request(url, "POST", headers, body, config);
    }

    public static String post(String url, Map headers, byte[] body) {
        return post(url, headers, body, null);
    }

    public static String head(String url, Map headers, HttpRequestConfig config) {
        return request(url, "HEAD", headers, null, config);
    }

    public static String head(String url, Map headers) {
        return head(url, headers, null);
    }

    public static String options(String url, Map headers, HttpRequestConfig config) {
        return request(url, "OPTIONS", headers, null, config);
    }

    public static String options(String url, Map headers) {
        return options(url, headers, null);
    }

    public static String put(String url, Map headers, byte[] body, HttpRequestConfig config) {
        return request(url, "PUT", headers, body, config);
    }

    public static String put(String url, Map headers, byte[] body) {
        return put(url, headers, body, null);
    }

    public static String delete(String url, Map headers, HttpRequestConfig config) {
        return request(url, "DELETE", headers, null, config);
    }

    public static String delete(String url, Map headers) {
        return delete(url, headers, null);
    }

    public static String trace(String url, Map headers, byte[] body, HttpRequestConfig config) {
        return request(url, "TRACE", headers, body, config);
    }

    public static String trace(String url, Map headers, byte[] body) {
        return trace(url, headers, body, null);
    }

    public static String uploadMultipartFile(String url, Map headers, List files, HttpRequestConfig config) {
        ClientFailureMsg.requireNonEmpty(files, "上传文件为空");

        String boundary = IdHelp.nanoId();
        Map map = ToMap.get(NullHelp.isEmpty(headers) ? 4 : 4 + headers.size())
                .put("Accept", "*/*")
                .put("Transfer-Encoding", "gzip,deflate,binary")
                .put("Connection", "keep-alive")
                .put("Content-Type", "multipart/form-data; boundary=" + boundary)
                .build();
        if (NullHelp.nonEmpty(headers)) headers.forEach((k, v) -> {
            if (k.equalsIgnoreCase("Accept")
                    || k.equalsIgnoreCase("Transfer-Encoding")
                    || k.equalsIgnoreCase("Connection")
                    || k.equalsIgnoreCase("Content-Type")) return;
            map.put(k, v);
        });

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            for (MultipartFile file : files) {
                if (NullHelp.isEmpty(file.getBytes())) continue;
                baos.write(("--" + boundary + "\r\n").getBytes());
                baos.write(("Content-Disposition: form-data; name=\"" + file.getName() + "\"; filename=\"" + file.getFilename() + "\"\r\n").getBytes());
                baos.write(("Content-Type: application/octet-stream; charset=" + file.getCharset().name() + "\r\n").getBytes());
                baos.write("\r\n".getBytes());
                baos.write(file.getBytes());
                baos.write("\r\n".getBytes());
                baos.write(("--" + boundary + "--\r\n").getBytes());
            }
        } catch (IOException e) {
            throw PRException.of(e);
        }

        return post(url, map, baos.toByteArray(), config);
    }

    public static String uploadMultipartFile(String url, Map headers, List files) {
        return uploadMultipartFile(url, headers, files, null);
    }

    public static String uploadMultipartFile(String url, List files) {
        return uploadMultipartFile(url, null, files);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy