首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 解析網頁 JSON 數據實戰:HttpURLConnection + 官方 org.json 庫完整工具類封裝與測試

     編輯:Java 綜合教學

前言

在需要調用第三方 HTTP 接口獲取 JSON 數據的場景中,Java 開發者常面臨:HTTP 請求封裝、流轉字符串、JSON 解析三大步驟。本文提供一套完整的工具類封裝(HttpUtil、InputStreamUtil、JsonUtil),基於 JDK 原生 HttpURLConnection 與官方 org.json 庫,並通過實際測試類演示調用笑話接口的全流程。最後對比 Gson,指出官方庫的復雜性痛點。

一、工具類體系設計

1. HttpUtil —— 發送 POST 請求獲取輸入流

package com.dragon.java.jsonwebdata;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpUtil {
    public static InputStream getInputStreamByPost(String url, String parms) {
        try {
            HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setReadTimeout(5000);
            conn.setConnectTimeout(5000);
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);

            try (OutputStream os = conn.getOutputStream()) {
                os.write(parms.getBytes("UTF-8"));
            }

            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                return conn.getInputStream();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

改進點: 顯式指定 getBytes("UTF-8") 避免中文亂碼;使用 try-with-resources 關閉流。

2. InputStreamUtil —— 流轉字符串

package com.dragon.java.jsonwebdata;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class InputStreamUtil {
    public static String inputStreamToString(InputStream is) {
        StringBuilder sb = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }
}

注意: 原代碼 return line 只讀第一行,已修正為拼接完整響應體。

3. JsonUtil —— 官方 org.json 解析

package com.dragon.java.jsonwebdata;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;

public class JsonUtil {
    public static void jsonParse(String json) {
        List<Detail> details = new ArrayList<>();
        try {
            JSONObject root = new JSONObject(json);
            if ("000000".equals(root.optString("status"))) {
                // 假設 detail 為數組
                JSONArray array = root.optJSONArray("detail");
                if (array != null) {
                    for (int i = 0; i < array.length(); i++) {
                        JSONObject obj = array.getJSONObject(i);
                        Detail d = new Detail(
                                obj.getInt("id"),
                                obj.getInt("xhid"),
                                obj.getString("author"),
                                obj.getString("content"),
                                obj.getString("picUrl"),
                                obj.getString("status")
                        );
                        details.add(d);
                    }
                }
                details.forEach(System.out::println);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

// 數據實體類
class Detail {
    int id, xhid;
    String author, content, picUrl, status;
    public Detail(int id, int xhid, String author, String content, String picUrl, String status) {
        this.id = id; this.xhid = xhid; this.author = author; this.content = content; this.picUrl = picUrl; this.status = status;
    }
    @Override public String toString() {
        return "Detail{id=" + id + ", author='" + author + "', content='" + content + "'}";
    }
}

二、測試類調用實戰

package com.dragon.java.jsonwebdata;

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("請輸入頁數: ");
        int currentPage = scanner.nextInt();
        System.out.print("請輸入每頁笑話數: ");
        int size = scanner.nextInt();

        String url = "https://api.1-blog.com/biz/bizserver/xiaohua/list.do";
        String parms = "currentPage=" + currentPage + "&size=" + size;

        String json = InputStreamUtil.inputStreamToString(
                HttpUtil.getInputStreamByPost(url, parms)
        );
        JsonUtil.jsonParse(json);
    }
}

三、官方 org.json 庫痛點與 Gson 對比

維度org.json (官方)Gson (Google)
依賴體積極小(單文件)約 200KB
對象映射手動 getInt/getString 構造對象gson.fromJson(json, Detail.class) 一行搞定
泛型支持無 TypeToken 機制,List<T> 需手動循環完美支持 new TypeToken<List<Detail>>(){}.getType()
空值/異常處理易拋 JSONException,需大量 try-catch優雅處理 null,可配置序列化策略
性能一般優秀(流式解析 + 緩存)

四、最佳實踐建議

  1. 新項目首選 Gson / Jackson:開發效率、可維護性、性能全面優勢。
  2. 僅在極度受限環境(如古老 Android、嵌入式)使用 org.json。
  3. HTTP 客戶端升級:生產環境建議替換為 OkHttp、Apache HttpClient 5 或 Spring RestTemplate/WebClient,支持連接池、重試、攔截器等企業級特性。
  4. 異常處理規範化:工具類拋出自定義異常(如 ApiInvokeException),上層統一處理降級/告警。

五、總結

本文演示了從 HTTP 請求到 JSON 解析的完整鏈路代碼。雖然官方 org.json 庫零依賴、輕量,但其繁瑣的手動映射極大降低了開發效率。現代 Java 開發中,Gson/Jackson + OkHttp/HttpClient 是處理 REST API 的黃金組合,請根據項目約束合理選型。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved