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

com.star.net.http.HttpUtil Maven / Gradle / Ivy

The newest version!
package com.star.net.http;

import com.star.collection.array.ArrayUtil;
import com.star.collection.iter.IterUtil;
import com.star.collection.map.MapUtil;
import com.star.exception.HttpException;
import com.star.io.CharsetUtil;
import com.star.io.IoUtil;
import com.star.net.URLUtil;
import com.star.regex.RegexUtil;
import com.star.string.StringUtil;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

/**
 * Http请求工具类
 *
 * @author http://git.oschina.net/loolly/hutool
 */
public final class HttpUtil {
    /**
     * 字符集正则
     */
    public final static Pattern CHARSET_PATTERN = Pattern.compile("charset=(.*?)$");

    /**
     * 构造方法
     */
    private HttpUtil() {
        // 防止被初始化
    }

    /**
     * 获取客户端ip
     *
     * @param request          请求
     * @param otherHeaderNames 头信息
     * @return ip
     */
    public static String getClientIP(final HttpServletRequest request, final String... otherHeaderNames) {
        String[] headers = new String[]{"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP"};
        if (otherHeaderNames != null && otherHeaderNames.length > 0) {
            headers = ArrayUtil.merge(otherHeaderNames);
        }

        String result = "";
        for (final String header : headers) {
            String ipStr = request.getHeader(header);
            if (!isUnknow(ipStr)) {
                result = getMultistageReverseProxyIp(ipStr);
                break;
            }
        }

        return StringUtil.isBlank(result) ? getMultistageReverseProxyIp(request.getRemoteAddr()) : result;

    }

    /**
     * 发送get或者delete请求
     *
     * @param urlString     链接
     * @param customCharset 编码
     * @param httpMethod    http方法
     * @return 响应
     */
    public static String get(final String urlString, final String customCharset, final HttpMethod httpMethod) {
        final HttpRequest httpRequest = HttpRequest.getRequest(urlString, httpMethod);
        if (!StringUtil.isBlank(customCharset)) {
            httpRequest.setCharset(customCharset);
        }
        return httpRequest.execute().getBody();
    }

    /**
     * 发送post或者put请求
     *
     * @param urlString  链接
     * @param httpMethod http方法
     * @param params     参数
     * @return 响应
     */
    public static String post(final String urlString, final String params, final HttpMethod httpMethod) {
        return HttpRequest.getRequest(urlString, httpMethod).body(params).execute().getBody();
    }

    /**
     * 发送post或者put请求
     *
     * @param urlString  链接
     * @param httpMethod http方法
     * @param paramMap   参数
     * @return 响应
     */
    public static String post(final String urlString, final Map paramMap, final HttpMethod httpMethod) {
        return HttpRequest.getRequest(urlString, httpMethod).setForm(paramMap).execute().getBody();
    }

    /**
     * 获得远程String
     *
     * @param url           链接
     * @param customCharset 编码
     * @return 响应
     */
    public static String downloadString(final String url, final String customCharset) {
        InputStream input;
        try {
            input = URLUtil.url(url).openStream();
        } catch (IOException e) {
            throw new HttpException(StringUtil.format("open stream from url failure,the reason is: {}", e.getMessage()),
                    e);
        }
        try {
            return IoUtil.read(input).toString(CharsetUtil.charset(customCharset));
        } finally {
            IoUtil.close(input);
        }
    }

    /**
     * 下载文件
     *
     * @param url  链接
     * @param file 文件
     * @return 下载的字节数
     */
    public static long downloadFile(final String url, final File file) {
        InputStream input = null;
        OutputStream output = null;
        try {
            input = URLUtil.url(url).openStream();
            output = new FileOutputStream(file);
            return IoUtil.copy(input, output, 0);
        } catch (IOException e) {
            throw new HttpException(StringUtil.format("download faile failure,the reason is: {}", e.getMessage()), e);
        } finally {
            IoUtil.close(input);
            IoUtil.close(output);
        }
    }

    /**
     * 将Map形式的Form表单数据转换为Url参数形式
     *
     * @param paramMap 参数
     * @return 参数形式的字符串
     */
    public static String toParams(final Map paramMap) {
        return MapUtil.isEmpty(paramMap) ? "" : IterUtil.join(paramMap.entrySet(), "&");
    }

    /**
     * 将Map形式的Form表单数据转换为Url参数形式
     *
     * @param paramMap 参数
     * @param charset  编码
     * @return 参数信息的字符串
     */
    public static String toParams(final Map paramMap, final String charset) {
        final Map maps = new ConcurrentHashMap<>(paramMap.size());
        for (final Entry entry : paramMap.entrySet()) {
            maps.put(URLUtil.encode(entry.getKey(), charset), URLUtil.encode(entry.getValue().toString(), charset));
        }
        return toParams(maps);
    }

    /**
     * 将url参数解析为Map
     *
     * @param paramsStr 参数形式的字符串
     * @param charset   编码
     * @return map
     */
    public static Map> decodeParams(final String paramsStr, final String charset) {
        // 直接用分隔符截成n个数组来处理,逻辑简单点也能达到效果
        Map> params;

        if (StringUtil.isBlank(paramsStr)) {
            params = Collections.emptyMap();
        } else {

            // 去掉Path部分

            final int pathEndPos = paramsStr.indexOf('?');

            String url = pathEndPos > 0 ? paramsStr.substring(pathEndPos + 1) : paramsStr;

            url = URLUtil.decode(url, charset);

            final String[] kvPairs = url.split("&");

            params = new LinkedHashMap<>(kvPairs.length);

            for (final String kv : kvPairs) {
                if (kv.indexOf('=') == -1) {
                    addParam(params, kv, "");
                } else {
                    final String[] temp = kv.split("=");
                    addParam(params, temp[0], temp.length == 2 ? temp[1] : "");
                }

            }
        }

        return params;


    }

    /**
     * 将表单数据加到URL中(用于GET表单提交)
     *
     * @param url  链接
     * @param form 参数
     * @return 带参数的字符串
     */
    public static String urlWithForm(final String url, final Map form) {
        final String queryString = toParams(form);
        return urlWithForm(url, queryString);
    }

    /**
     * 将表单数据字符串加到URL中(用于GET表单提交)
     *
     * @param url         链接
     * @param queryString 参数
     * @return 带参数的字符串
     */
    public static String urlWithForm(final String url, final String queryString) {
        final StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(url);
        if (!StringUtil.isBlank(queryString)) {
            if (url.indexOf('?') != -1) {
                // 原URL已经带参数

                stringBuffer.append('&').append(queryString);
            }
            stringBuffer.append(url.lastIndexOf('?') == url.length() ? queryString : "?" + queryString);
        }

        return stringBuffer.toString();
    }

    /**
     * 从Http连接的头信息中获得字符集
     *
     * @param conn 链接
     * @return 编码
     */
    public static String getCharset(final HttpURLConnection conn) {
        return RegexUtil.get(CHARSET_PATTERN, conn.getContentType(), 1);
    }

    /**
     * 从多级反向代理中获得第一个非unknown IP地址
     *
     * @param ipStr ip
     * @return 真实ip
     */
    public static String getMultistageReverseProxyIp(final String ipStr) {
        String resultIp = "";
        if (ipStr != null && ipStr.indexOf(',') > 0) {
            final String[] ips = ipStr.split(",");
            for (final String subIp : ips) {
                if (!isUnknow(subIp)) {
                    resultIp = subIp;
                    break;
                }
            }
        }
        return StringUtil.isBlank(resultIp) ? ipStr : resultIp;
    }

    /**
     * 检测给定字符串是否为未知,多用于检测HTTP请求相关
     *
     * @param checkString 字符串
     * @return 是否未知
     */
    public static boolean isUnknow(final String checkString) {
        return StringUtil.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
    }

    /**
     * 从流中读取内容
     * 

* reponse读的时候需要依赖这方法,但传入inputstream就得不到页面的charset了 *

* 修改下,单纯的通过input和charset来得到string * * @param url 链接 * @param charset 编码 * @param useContentCharset 使用内容的编码 * @return 响应 */ public static String getString(final URL url, final String charset, final boolean useContentCharset) { HttpURLConnection connection; InputStream input; try { connection = (HttpURLConnection) url.openConnection(); input = connection.getInputStream(); } catch (IOException e1) { throw new HttpException(StringUtil.format("获取url输入流失败: {}", e1.getMessage()), e1); } String result; if (useContentCharset) { final String charsetInContent = getCharset(connection); final StringBuilder content = new StringBuilder(); final BufferedReader reader = IoUtil.getReader(input, StringUtil.isBlank(charsetInContent) ? Charset.defaultCharset() : Charset.forName(charsetInContent)); String line = null; try { while ((line = reader.readLine()) != null) { content.append(line).append('\n'); } } catch (IOException e) { throw new HttpException(StringUtil.format("获取url输入流中的字符串失败: {}", e.getMessage()), e); } finally { IoUtil.close(reader); } result = content.toString(); } else { result = IoUtil.read(input, charset); } return result; } /** * 根据文件扩展名获得MimeType * * @param filePath 文件名 * @return MimeType */ public static String getMimeType(final String filePath) { return URLConnection.getFileNameMap().getContentTypeFor(filePath); } /** * 将键值对加入到值为List类型的Map中 * * @param params 参数 * @param name 键 * @param value 值 * @return 是否添加成功 */ private static boolean addParam(final Map> params, final String name, final String value) { List values = params.get(name); if (values == null) { values = new ArrayList<>(1); // 一般是一个参数 params.put(name, values); } values.add(value); return true; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy