JavaHTTP请求工具类HTTPUtils

时间:2025-03-12 08:28:53
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.w3c.dom.*; import org.xml.sax.InputSource; import javax.imageio.ImageIO; import javax.net.ssl.*; import javax.swing.*; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; public class HTTPUtils { // 请求头示例 public static Map<String, String> headers = new HashMap<String, String>() {{ // 设置接收内容类型 put("Accept", "application/json"); // 设置发送内容类型 put("Content-Type", "application/json;charset=UTF-8"); // 设置字符集 put("charset", "UTF-8"); // 设置访问者系统引擎版本、浏览器信息的字段信息,此处伪装成用户通过浏览器访问 put("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); }}; // 禁用 SSL 验证 public static void disableSSLVerification() { try { // 创建不验证证书链的 TrustManager TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; // 安装 TrustManager SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); // 创建验证所有主机名的 HostnameVerifier HostnameVerifier allHostsValid = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; // 安装 HostnameVerifier HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } } // 将请求头键值对添加到 HTTP 请求中 public static void addHeadersToRequest(HttpURLConnection httpConn, Map<String, ?> headers) { if (headers != null) { for (Map.Entry<String, ?> entry : headers.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); if (value.getClass().isArray()) { // 如果是数组类型,则遍历数组并添加请求头 for (Object v : (Object[]) value) { httpConn.setRequestProperty(key, v.toString()); } } else { // 如果不是数组类型,则直接添加请求头 httpConn.setRequestProperty(key, value.toString()); } } } } // 将请求参数拼接进 URL public static String concatParamsToURL(String staticURL, String paramsStr){ return staticURL + paramsStr; } public static String concatParamsToURL(String staticURL, Map<String, ?> params) throws Exception { // staticURL 是字符串形式的静态 URL // params 键与值分别是参数名与参数值,URL 有重复同名参数时将多个值放进数组 // 判断参数是否为空 if (params.isEmpty()) { return staticURL; } StringBuilder sb = new StringBuilder(staticURL); // 判断 URL 中是否已经包含参数 boolean hasParams = staticURL.indexOf("?") != -1; // 遍历参数 for (Map.Entry<String, ?> entry : params.entrySet()) { String key = entry.getKey(); // 参数名 Object value = entry.getValue(); // 参数值 // 判断参数值是否为数组 if (value.getClass().isArray()) { // 如果是数组,遍历数组并添加参数 for (Object v : (Object[]) value) { sb.append(hasParams ? "&" : "?") .append(URLEncoder.encode(key, "utf-8")) .append("=") .append(URLEncoder.encode(v.toString(), "utf-8")); hasParams = true; } } else { // 如果不是数组,直接添加参数 sb.append(hasParams ? "&" : "?") .append(URLEncoder.encode(key, "utf-8")) .append("=") .append(URLEncoder.encode(value.toString(), "utf-8")); hasParams = true; } } return sb.toString(); } // 发起 HTTP 请求并获取响应内容 // 重载 requestHTTPContent(),相当于参数有默认值 public static String requestHTTPContent(String strURL) throws Exception { return requestHTTPContent(strURL, "GET", null, null); } public static String requestHTTPContent(String strURL, String method) throws Exception { return requestHTTPContent(strURL, method, null, null); } public static String requestHTTPContent(String strURL, String method, Map<String, ?> headers) throws Exception { return requestHTTPContent(strURL, method, headers, null); } public static String requestHTTPContent(String strURL, String method, Map<String, ?> headers, Map<String, ?> params) throws Exception { // strURL 是 String 类型的 URL // method 是 String 类型的请求方法,为 "GET" 或 "POST" // headers 键与值分别是请求头名与请求头值,有重复同名请求头时将多个值放进数组 // params 键与值分别是参数名与参数值,URL 有重复同名参数时将多个值放进数组 // 忽略验证 https 中 SSL 证书 disableSslVerification(); // GET 方法下,query 参数拼接在 URL 字符串末尾 if(method.equals("GET") && params != null) { strURL = concatParamsToURL(strURL, params); } System.out.println(strURL); URL url = new URL(strURL); HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); httpConn.setRequestMethod(method); // 添加 HTTP 请求头 addHeadersToRequest(httpConn, headers); // 请求时是否使用缓存 httpConn.setUseCaches(false); // POST 方法请求必须设置下面两项 // 设置是否从 HttpUrlConnection 的对象写 httpConn.setDoOutput(true); // 设置是否从 HttpUrlConnection 的对象读入 httpConn.setDoInput(true); // 此处默认 POST 方法发送的内容就是 JSON 形式的 body 参数,可以自行更改 if(method.equals("POST") && params!=null) { // 发送请求 OutputStream out = new DataOutputStream(httpConn.getOutputStream()); // getBytes() 作用为根据参数给定的编码方式,将一个字符串转化为一个字节数组 out.write(JSON.toJSONString(params).getBytes("UTF-8")); out.flush(); } else{ //发送请求 httpConn.connect(); } String contentType = httpConn.getContentType(); String result = readResponseContent(httpConn); // 输出响应内容 // outputResponseContent(result, contentType); return result; } // 异步 HTTP 请求 public static CompletableFuture<String> asyncHTTPRequest(String strURL, String method, Map<String, ?> headers, Map<String, ?> params) { return CompletableFuture.supplyAsync(() -> { try { return requestHTTPContent(strURL, method, headers, params); } catch (Exception e) { e.printStackTrace(); return null; } }); } // 读取响应内容 public static String readResponseContent(HttpURLConnection httpConn) throws Exception { try (BufferedReader reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream()))) { // 此处不用 StringBuffer 而用 StringBuilder 是出于线程安全的考虑 StringBuilder builder = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { builder.append(line); } return builder.toString(); } } // 输出响应内容 public static void outputResponseContent(String responseContent, String contentType) throws Exception { // contentType 是接收内容类型 // 响应内容为 JSON 格式 if (contentType.contains("application/json")) { // 解析 JSON 字符串为 JSON 对象 JSONObject jsonObj = JSON.parseObject(responseContent); printJSON(jsonObj,0); } // 响应内容为 XML 格式 else if (contentType.contains("application/xml")) { // 创建 DocumentBuilderFactory 对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建 DocumentBuilder 对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 将 XML 解析成 Document 对象 Document doc = builder.parse(new InputSource(new StringReader(responseContent))); printXML(doc); } // 响应内容为图像 else if (contentType.contains("image/jpeg") || contentType.contains("image/png")) { // 将响应内容解码为图片 byte[] imageBytes = responseContent.getBytes(); ByteArrayInputStream bis = new ByteArrayInputStream(imageBytes); BufferedImage image = ImageIO.read(bis); viewImage(new ImageIcon(image)); } // 响应内容为 PDF 文档 else if (contentType.contains("application/pdf")) { System.out.println("[PDF document]"); } // 响应内容为二进制数据流 else if (contentType.contains("application/octet-stream")) { System.out.println("[Binary data]"); } // 响应内容为 HTML 格式、纯文本格式 else if (contentType.contains("text/html") || contentType.contains("text/plain")) { System.out.println(responseContent); } // 响应内容为其他格式 else { System.out.println(responseContent); } } // 打印 JSON public static void printJSON(JSONObject jsonObj, int level) { if (jsonObj != null) { for (Map.Entry<String, Object> entry : jsonObj.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); String indent = String.join("", Collections.nCopies(level, "\t")); // 缩进 if (value instanceof JSONObject) { // 嵌套对象 System.out.println(indent + key + " = {"); printJSON((JSONObject) value, level + 1); // 增加嵌套层级 System.out.println(indent + "}"); } else { // 非嵌套对象 System.out.println(indent + key + " = " + value.toString()); } } } } // 打印 XML public static void printXML(Document doc) { Element root = doc.getDocumentElement(); printXML(System.out, root, 0); } // 打印 XML private static void printXML(PrintStream ps, Element element, int indent) { printTrunk(ps, indent); ps.printf("├─ 元素: %s\n", element.getNodeName()); NamedNodeMap attributes = element.getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { Attr attribute = (Attr) attributes.item(i); printTrunk(ps, indent + 1); ps.printf("├─ 属性: %s = %s\n", attribute.getName(), attribute.getValue()); } NodeList children = element.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (child.getNodeType() == Node.ELEMENT_NODE) { printXML(ps, (Element) child, indent + 1); } else if (child.getNodeType() == Node.TEXT_NODE) { String text = child.getNodeValue().trim(); if (!text.isEmpty()) { printTrunk(ps, indent + 1); ps.printf("└─ 文本: %s\n", text); } } } } // 打印 XML private static void printTrunk(PrintStream ps, int indent) { for (int i = 0; i < indent; i++) { ps.print("| "); } } // 浏览图像 private static void viewImage(ImageIcon imageIcon) { JLabel label = new JLabel(imageIcon); JFrame frame = new JFrame("图片显示"); frame.getContentPane().add(label, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } }