001package top.cenze.utils.http.request;
002
003import cn.hutool.core.util.StrUtil;
004import cn.hutool.crypto.digest.DigestUtil;
005import cn.hutool.http.HttpRequest;
006import cn.hutool.http.HttpUtil;
007import cn.hutool.http.Method;
008import com.alibaba.fastjson.JSON;
009import com.alibaba.fastjson.parser.Feature;
010import lombok.extern.slf4j.Slf4j;
011import org.apache.commons.lang3.StringUtils;
012import org.springframework.util.CollectionUtils;
013
014import javax.net.ssl.*;
015import java.io.*;
016import java.net.HttpURLConnection;
017import java.net.URL;
018import java.util.*;
019
020/**
021 * https请求工具
022 * author: cz
023 */
024
025@Slf4j
026public class HttpsUtil {
027
028    public static <T> T post(String url, Map<String, String> headers, Class<T> clazz) {
029        return request(url, new HashMap<>(), headers, Method.POST, clazz);
030    }
031
032    public static <T> T postMap(String url, Map<String, Object> params, Map<String, String> headers, Class<T> clazz) {
033        return request(url, params, headers, Method.POST, clazz);
034    }
035
036    public static <T> T postMap(String url, Map<String, Object> params, Class<T> clazz) {
037        return request(url, params, null, Method.POST, clazz);
038    }
039
040    public static <T> T postObj(String url, Object obj, Class<T> clazz) {
041        return request(url, JSON.toJSONString(obj), null, Method.POST, clazz);
042    }
043
044    public static <T> T postObj(String url, Object obj, Map<String, String> headers, Class<T> clazz) {
045        return request(url, JSON.toJSONString(obj), headers, Method.POST, clazz);
046    }
047
048    public static <T> T postStr(String url, String str, Map<String, String> headers, Class<T> clazz) {
049        return request(url, str, headers, Method.POST, clazz);
050    }
051
052    public static <T> T get(String url, Map<String, String> headers, Class<T> clazz) {
053        return request(url, new HashMap<>(), headers, Method.GET, clazz);
054    }
055
056    public static <T> T getMap(String url, Map<String, Object> params, Map<String, String> headers, Class<T> clazz) {
057        return request(url, params, headers, Method.GET, clazz);
058    }
059
060    public static <T> T getObj(String url, Object obj, Map<String, String> headers, Class<T> clazz) {
061        return request(url, JSON.toJSONString(obj), headers, Method.GET, clazz);
062    }
063
064    public static <T> T getStr(String url, String str, Map<String, String> headers, Class<T> clazz) {
065        return request(url, str, headers, Method.GET, clazz);
066    }
067
068    public static <T> T putObj(String url, Object obj, Map<String, String> headers, Class<T> clazz) {
069        return request(url, JSON.toJSONString(obj), headers, Method.PUT, clazz);
070    }
071
072    public static <T> T del(String url, Map<String, String> headers, Class<T> clazz) {
073        return request(url, "", headers, Method.DELETE, clazz);
074    }
075
076    public static <T> T delObj(String url, Object obj, Map<String, String> headers, Class<T> clazz) {
077        return request(url, JSON.toJSONString(obj), headers, Method.DELETE, clazz);
078    }
079
080    public static String getCookie(String url, Map<String, Object> params) {
081        HttpRequest httpRequest = HttpUtil.createGet(url);
082        httpRequest.form(params);
083
084        log.info("getCookie url: {}, req: {}", url, JSON.toJSONString(params));
085        String result = httpRequest.execute()
086                .getCookieStr();
087        log.info("getCookie result: {}", result);
088
089        return result;
090    }
091
092    public static <T> T request(String url, String str, Map<String, String> headers, Method method, Class<T> clazz) {
093        if (null == method) {
094            method = Method.POST;
095        }
096
097        HttpRequest httpRequest = HttpUtil.createRequest(method, url);
098        httpRequest.setConnectionTimeout(60000000);
099
100        if (!CollectionUtils.isEmpty(headers)) {
101            for (Map.Entry<String, String> head : headers.entrySet()) {
102                httpRequest.header(head.getKey(), head.getValue());
103            }
104        }
105
106        if (!StringUtils.isBlank(str)) {
107            httpRequest.body(str);
108        }
109
110        log.info("request url: {}, req: {}", url, str);
111        String result = httpRequest.execute().body();
112        log.info("request result: {}", result);
113
114        if (!StringUtils.isBlank(result)) {
115            if (null != clazz) {
116                try {
117                    return JSON.parseObject(result, clazz);
118                } catch (Exception e) {
119                    log.error("request err: {}, result: {}", e.getMessage(), result);
120                }
121            } else {
122                return (T) result;
123            }
124        }
125
126        return null;
127    }
128
129    public static <T> T request(String url, Map<String, Object> params, Map<String, String> headers, Method method, Class<T> clazz) {
130        if (null == method) {
131            method = Method.POST;
132        }
133
134        HttpRequest httpRequest = HttpUtil.createRequest(method, url);
135
136        if (!CollectionUtils.isEmpty(headers)) {
137            for (Map.Entry<String, String> head : headers.entrySet()) {
138                httpRequest.header(head.getKey(), head.getValue());
139            }
140        }
141
142        if (!CollectionUtils.isEmpty(params)) {
143            httpRequest.form(params);
144        }
145
146        log.info("request url: {}, req: {}", url, JSON.toJSONString(params));
147        String result = httpRequest.execute().body();
148        log.info("request result: {}", result);
149
150        if (!StringUtils.isBlank(result)) {
151            if (null != clazz) {
152                try {
153                    return JSON.parseObject(result, clazz);
154                } catch (Exception e) {
155                    log.error("request err: {}, result: {}", e.getMessage(), result);
156                }
157            } else {
158                return (T) result;
159            }
160        }
161
162        return null;
163    }
164
165
166    /**
167     * 发送HTTPS请求
168     * 访问https资源时,忽略证书信任问题
169     * @param toURL 请求地址
170     * @param data 请求参数
171     * @param dateType 参数类型,“JSON”,other
172     * @return
173     * @throws Exception
174     */
175    public static String httpsPost(String toURL, String data, String dateType)
176            throws Exception {
177        StringBuffer bs = new StringBuffer();
178
179        //  直接通过主机认证
180        HostnameVerifier hv = new HostnameVerifier() {
181            @Override
182            public boolean verify(String arg0, SSLSession arg1) {
183                return true;
184            }
185        };
186        //  配置认证管理器
187        javax.net.ssl.TrustManager[] trustAllCerts = {new TrustAllTrustManager()};
188        SSLContext sc = SSLContext.getInstance("SSL");
189        SSLSessionContext sslsc = sc.getServerSessionContext();
190        sslsc.setSessionTimeout(0);
191        sc.init(null, trustAllCerts, null);
192        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
193        //  激活主机认证
194        HttpsURLConnection.setDefaultHostnameVerifier(hv);
195        URL url = new URL(toURL);
196        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
197        connection.setConnectTimeout(30000);
198        connection.setReadTimeout(30000);
199        connection.setDoOutput(true);
200        if("JSON".equalsIgnoreCase(dateType)){
201            connection.setRequestProperty("Content-Type","application/json;chert=UTF-8");
202        }else{
203            connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
204        }
205        OutputStreamWriter out = new OutputStreamWriter(
206                connection.getOutputStream(), "UTF-8");
207        out.write(data);
208        out.flush();
209        out.close();
210        connection.connect();
211        int code = ((HttpURLConnection) connection).getResponseCode();
212        InputStream is =  null;
213        if (code == 200) {
214            is = connection.getInputStream(); // 得到网络返回的正确输入流
215        } else {
216            is = ((HttpURLConnection) connection).getErrorStream(); // 得到网络返回的错误输入流
217        }
218        BufferedReader buffer = new BufferedReader(new InputStreamReader(is,"UTF-8"));
219
220        String l = null;
221        while ((l = buffer.readLine()) != null) {
222            bs.append(l);
223        }
224        //return bs.toString();
225        return String.valueOf(bs);
226    }
227
228    /**
229     * 对象转有map
230     *
231     * @param obj
232     * @return
233     */
234    public static Map<String, Object> objToMap(Object obj) {
235        return JSON.parseObject(JSON.toJSONString(obj), HashMap.class, Feature.OrderedField);
236    }
237
238    public static StringBuilder mapToSortStr(Map<String, Object> params) {
239        // 移除值为空的
240        params.entrySet().removeIf(
241                entry -> Objects.isNull(entry.getValue()) ||
242                "".equals(entry.getValue()));
243
244        List<Map.Entry<String, Object>> infoIds = new ArrayList<>(params.entrySet());
245        // 对所有传入参数按照字段名的ASCII码从小到大排序(字典序)
246        infoIds.sort((o1, o2) -> o1.getKey().compareToIgnoreCase(o2.getKey()));
247        StringBuilder sb = new StringBuilder();
248        for (Map.Entry<String, Object> infoId : infoIds) {
249            sb.append(infoId.getKey());
250            sb.append("=");
251            sb.append(infoId.getValue());
252            sb.append("&");
253        }
254
255        // 删除末尾的 "&"
256        sb.deleteCharAt(sb.length() - 1);
257
258        return sb;
259    }
260
261    /**
262     * map按Key顺序排序
263     * @param params
264     * @return
265     */
266    public static LinkedHashMap<String, Object> mapToSortMap(Map<String, Object> params) {
267        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
268
269        // 移除值为空的
270        params.entrySet().removeIf(
271                entry -> Objects.isNull(entry.getValue()) ||
272                        "".equals(entry.getValue()));
273
274        List<Map.Entry<String, Object>> infoIds = new ArrayList<>(params.entrySet());
275
276        // 对所有传入参数按照字段名的ASCII码从小到大排序(字典序)
277        infoIds.sort((o1, o2) -> o1.getKey().compareToIgnoreCase(o2.getKey()));
278        for (Map.Entry<String, Object> infoId : infoIds) {
279            map.put(infoId.getKey(), infoId.getValue());
280        }
281
282        return map;
283    }
284
285    /**
286     * obj 转 mac buff
287     * @param obj
288     * @return
289     */
290    public static String objToMacBuff(Object obj) {
291        StringBuilder sb = new StringBuilder();
292
293        Map<String, Object> mapParams = objToMap(obj);
294
295        LinkedHashMap<String, Object> map = mapToSortMap(mapParams);
296
297        for (Map.Entry<String, Object> e : mapParams.entrySet()) {
298            sb.append(" ").append(e.getValue());
299        }
300
301        return StrUtil.trim(sb.toString());
302    }
303
304    /**
305     * 获取排序参数签名
306     * @param key
307     * @return
308     * @throws UnsupportedEncodingException
309     */
310    public static String getSign(StringBuilder sb, String key) throws UnsupportedEncodingException {
311        // 最后拼接上key得到signTemp字符串
312        String signTemp = sb.append(key).toString();
313
314        // 对signTemp进行SHA-256运算,再将得到的字符串所有字符转换为大写,得到sign值signValue
315        String signValue = DigestUtil.sha256Hex(signTemp).toUpperCase();
316
317        return signValue;
318    }
319
320    /**
321     * 获取排序参数签名
322     * @param key
323     * @return
324     * @throws UnsupportedEncodingException
325     */
326    public static String getSign(Object obj, String key) throws UnsupportedEncodingException {
327        Map<String, Object> params = objToMap(obj);
328
329        StringBuilder sb = mapToSortStr(params);
330
331        String sign = getSign(sb, key);
332
333        return sign;
334    }
335
336    /**
337     * 获取排序参数签名(含签名参数)
338     * @param obj
339     * @param key
340     * @return
341     * @throws UnsupportedEncodingException
342     */
343    public static String getParamsAndSign(Object obj, String key) throws UnsupportedEncodingException {
344        Map<String, Object> params = objToMap(obj);
345
346        StringBuilder sb = mapToSortStr(params);
347
348        String sign = getSign(sb, key);
349
350        sb.append("&sign=").append(sign);
351
352        return sb.toString();
353    }
354}