You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解析任意类型JSON并提取其中的字符串值?

提取复杂JSON中的所有字符串值

嘿,我看你需要解析任意结构的JSON(不管是对象还是嵌套数组),只提取其中所有的字符串值对吧?结合你已经写了一部分的UrlActions类,我给你完善两种可行的Java实现方案,不管JSON结构多复杂都能轻松提取:

方案一:用Jackson库(推荐,处理复杂结构更高效)

Jackson是Java生态中处理JSON最常用的库之一,它的流式API可以逐Token遍历JSON,不需要提前定义实体类,完美适配任意JSON结构。

1. 先添加Maven依赖

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version> <!-- 建议使用最新稳定版 -->
</dependency>

2. 完整实现代码

我把你的readAll方法补全,再加上核心的JSON解析逻辑:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class UrlActions {

    private static String readAll(Reader rd) throws IOException {
        StringBuilder sb = new StringBuilder();
        int cp;
        while ((cp = rd.read()) != -1) {
            sb.append((char) cp);
        }
        return sb.toString();
    }

    // 从指定URL获取JSON并提取所有字符串值
    public static List<String> extractAllStringsFromJsonUrl(String urlStr) throws IOException {
        URL url = new URL(urlStr);
        try (InputStreamReader reader = new InputStreamReader(url.openStream())) {
            String jsonContent = readAll(reader);
            return extractAllStringsFromJson(jsonContent);
        }
    }

    // 解析JSON字符串,提取所有字符串值
    public static List<String> extractAllStringsFromJson(String jsonContent) throws IOException {
        List<String> stringValues = new ArrayList<>();
        ObjectMapper objectMapper = new ObjectMapper();
        
        try (JsonParser parser = objectMapper.getFactory().createParser(jsonContent)) {
            JsonToken token;
            while ((token = parser.nextToken()) != null) {
                // 只要遇到字符串类型的Token,就把值加入列表
                if (token == JsonToken.VALUE_STRING) {
                    stringValues.add(parser.getText());
                }
                // 其他类型(对象、数组、数字等)会自动遍历子元素,无需手动递归
            }
        }
        return stringValues;
    }

    // 测试示例:调用你提供的Yahoo财经JSON链接
    public static void main(String[] args) {
        try {
            String jsonUrl = "https://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json";
            List<String> strings = extractAllStringsFromJsonUrl(jsonUrl);
            System.out.println("提取到的所有字符串值:");
            strings.forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

代码说明

  • readAll:你已经写了核心逻辑,我补全了返回值,用来把输入流的内容转为完整的JSON字符串。
  • extractAllStringsFromJsonUrl:负责从指定URL获取JSON流,转交给解析方法。
  • extractAllStringsFromJson:核心逻辑,用Jackson的流式解析器逐Token遍历,不管JSON嵌套多少层,只要是字符串就提取,完全适配任意结构。

方案二:用org.json库(轻量,适合简单场景)

如果你不想引入Jackson这样的大库,也可以用轻量的org.json库,通过递归遍历JSON对象和数组来提取字符串:

1. 添加Maven依赖

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20230618</version>
</dependency>

2. 完整实现代码

import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class UrlActions {

    private static String readAll(Reader rd) throws IOException {
        StringBuilder sb = new StringBuilder();
        int cp;
        while ((cp = rd.read()) != -1) {
            sb.append((char) cp);
        }
        return sb.toString();
    }

    public static List<String> extractAllStringsFromJsonUrl(String urlStr) throws IOException {
        URL url = new URL(urlStr);
        try (InputStreamReader reader = new InputStreamReader(url.openStream())) {
            String jsonContent = readAll(reader);
            // 先判断根节点是对象还是数组
            Object jsonRoot;
            if (jsonContent.trim().startsWith("[")) {
                jsonRoot = new JSONArray(jsonContent);
            } else {
                jsonRoot = new JSONObject(jsonContent);
            }
            return extractAllStrings(jsonRoot);
        }
    }

    // 递归遍历JSON结构,提取所有字符串
    private static List<String> extractAllStrings(Object json) {
        List<String> stringValues = new ArrayList<>();
        if (json instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) json;
            // 遍历JSON对象的所有键值对
            for (Map.Entry<String, Object> entry : jsonObj.toMap().entrySet()) {
                Object value = entry.getValue();
                if (value instanceof String) {
                    stringValues.add((String) value);
                } else {
                    // 非字符串类型,递归处理
                    stringValues.addAll(extractAllStrings(value));
                }
            }
        } else if (json instanceof JSONArray) {
            JSONArray jsonArray = (JSONArray) json;
            // 遍历JSON数组的所有元素
            for (int i = 0; i < jsonArray.length(); i++) {
                Object element = jsonArray.get(i);
                if (element instanceof String) {
                    stringValues.add((String) element);
                } else {
                    // 非字符串元素,递归处理
                    stringValues.addAll(extractAllStrings(element));
                }
            }
        }
        // 数字、布尔、null等类型直接忽略
        return stringValues;
    }

    // 测试示例
    public static void main(String[] args) {
        try {
            String jsonUrl = "https://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json";
            List<String> strings = extractAllStringsFromJsonUrl(jsonUrl);
            System.out.println("提取到的所有字符串值:");
            strings.forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

代码说明

这个方案通过递归遍历JSON的每个节点,判断节点类型:如果是字符串就加入列表,如果是对象或数组就继续递归,直到所有字符串都被提取。


内容的提问来源于stack exchange,提问作者Adeel Faisal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:12:44