package com.iailab.framework.common.util.http; import cn.hutool.core.codec.Base64; import cn.hutool.core.map.TableMap; import cn.hutool.core.net.url.UrlBuilder; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; import javax.servlet.http.HttpServletRequest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URI; import java.net.URL; import java.net.URLConnection; import java.nio.charset.Charset; import java.util.List; import java.util.Map; /** * HTTP 工具类 * * @author iailab */ public class HttpUtils { @SuppressWarnings("unchecked") public static String replaceUrlQuery(String url, String key, String value) { UrlBuilder builder = UrlBuilder.of(url, Charset.defaultCharset()); // 先移除 TableMap query = (TableMap) ReflectUtil.getFieldValue(builder.getQuery(), "query"); query.remove(key); // 后添加 builder.addQuery(key, value); return builder.build(); } private String append(String base, Map query, boolean fragment) { return append(base, query, null, fragment); } /** * 拼接 URL * * copy from Spring Security OAuth2 的 AuthorizationEndpoint 类的 append 方法 * * @param base 基础 URL * @param query 查询参数 * @param keys query 的 key,对应的原本的 key 的映射。例如说 query 里有个 key 是 xx,实际它的 key 是 extra_xx,则通过 keys 里添加这个映射 * @param fragment URL 的 fragment,即拼接到 # 中 * @return 拼接后的 URL */ public static String append(String base, Map query, Map keys, boolean fragment) { UriComponentsBuilder template = UriComponentsBuilder.newInstance(); UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(base); URI redirectUri; try { // assume it's encoded to start with (if it came in over the wire) redirectUri = builder.build(true).toUri(); } catch (Exception e) { // ... but allow client registrations to contain hard-coded non-encoded values redirectUri = builder.build().toUri(); builder = UriComponentsBuilder.fromUri(redirectUri); } template.scheme(redirectUri.getScheme()).port(redirectUri.getPort()).host(redirectUri.getHost()) .userInfo(redirectUri.getUserInfo()).path(redirectUri.getPath()); if (fragment) { StringBuilder values = new StringBuilder(); if (redirectUri.getFragment() != null) { String append = redirectUri.getFragment(); values.append(append); } for (String key : query.keySet()) { if (values.length() > 0) { values.append("&"); } String name = key; if (keys != null && keys.containsKey(key)) { name = keys.get(key); } values.append(name).append("={").append(key).append("}"); } if (values.length() > 0) { template.fragment(values.toString()); } UriComponents encoded = template.build().expand(query).encode(); builder.fragment(encoded.getFragment()); } else { for (String key : query.keySet()) { String name = key; if (keys != null && keys.containsKey(key)) { name = keys.get(key); } template.queryParam(name, "{" + key + "}"); } template.fragment(redirectUri.getFragment()); UriComponents encoded = template.build().expand(query).encode(); builder.query(encoded.getQuery()); } return builder.build().toUriString(); } public static String[] obtainBasicAuthorization(HttpServletRequest request) { String clientId; String clientSecret; // 先从 Header 中获取 String authorization = request.getHeader("Authorization"); authorization = StrUtil.subAfter(authorization, "Basic ", true); if (StringUtils.hasText(authorization)) { authorization = Base64.decodeStr(authorization); clientId = StrUtil.subBefore(authorization, ":", false); clientSecret = StrUtil.subAfter(authorization, ":", false); // 再从 Param 中获取 } else { clientId = request.getParameter("client_id"); clientSecret = request.getParameter("client_secret"); } // 如果两者非空,则返回 if (StrUtil.isNotEmpty(clientId) && StrUtil.isNotEmpty(clientSecret)) { return new String[]{clientId, clientSecret}; } return null; } /** * 向指定URL发送GET方法的请求 * * @param url 发送请求的URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return URL 所代表远程资源的响应结果 */ public static String sendGet(String url, String param) { String result = ""; BufferedReader in = null; try { String urlNameString = url + "?" + param; URL realUrl = new URL(urlNameString); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 建立实际的连接 connection.connect(); // 获取所有响应头字段 Map> map = connection.getHeaderFields(); // 遍历所有的响应头字段 for (String key : map.keySet()) { System.out.println(key + "--->" + map.get(key)); } // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送GET请求出现异常!" + e); e.printStackTrace(); } // 使用finally块来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return result; } public static String sendGet(String url, Map params, String authorization) { String result = ""; BufferedReader in = null; try { StringBuilder sb = new StringBuilder(); sb.append(url); if (!CollectionUtils.isEmpty(params)) { sb.append("?"); params.forEach((k, v) -> { sb.append(k + "=" + v + "&"); }); sb.append("t=" + System.currentTimeMillis()); } String urlNameString = sb.toString(); URL realUrl = new URL(urlNameString); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("Authorization", authorization); connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 建立实际的连接 connection.connect(); // 获取所有响应头字段 Map> map = connection.getHeaderFields(); // 遍历所有的响应头字段 for (String key : map.keySet()) { System.out.println(key + "--->" + map.get(key)); } // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送GET请求出现异常!" + e); e.printStackTrace(); } // 使用finally块来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return result; } /** * 向指定 URL 发送POST方法的请求 * * @param url * @param json * @return */ public static String sendPost(String url, String json) { PrintWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); // 设置通用的请求属性 conn.setRequestProperty("content-type", "application/json"); conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new PrintWriter(conn.getOutputStream()); // 发送请求参数 out.print(json); // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送 POST 请求出现异常!" + e); e.printStackTrace(); } //使用finally块来关闭输出流、输入流 finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); } } return result; } /** * 向指定 URL 发送POST方法的请求 * * @param url * @param json * @param authorization * @return */ public static String sendPost(String url, String json, String authorization) { PrintWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); // 设置通用的请求属性 conn.setRequestProperty("Authorization", authorization); conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new PrintWriter(conn.getOutputStream()); // 发送请求参数 out.print(json); // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送 POST 请求出现异常!" + e); e.printStackTrace(); } //使用finally块来关闭输出流、输入流 finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); } } return result; } }