使用 json 路径访问 json 值?

Accessing json value using jsonpath?

我正在学习使用 jsonpath 的教程(https://www.baeldung.com/guide-to-jayway-jsonpath) and using the endpoint https://api.binance.com/api/v3/exchangeInfo 我正在尝试解析值 LOT_SIZE,交易品种 TRXEUR 的 stepSize。JSON 的具体部分包含返回的有效载荷包含在:

{
"symbol": "TRXEUR",
"status": "TRADING",
"baseAsset": "TRX",
"baseAssetPrecision": 8,
"quoteAsset": "EUR",
"quotePrecision": 8,
"quoteAssetPrecision": 8,
"baseCommissionPrecision": 8,
"quoteCommissionPrecision": 8,
"orderTypes": [
"LIMIT",
"LIMIT_MAKER",
"MARKET",
"STOP_LOSS_LIMIT",
"TAKE_PROFIT_LIMIT"
],
"icebergAllowed": true,
"ocoAllowed": true,
"quoteOrderQtyMarketAllowed": true,
"isSpotTradingAllowed": true,
"isMarginTradingAllowed": false,
"filters": [
{
"filterType": "PRICE_FILTER",
"minPrice": "0.00010000",
"maxPrice": "1000.00000000",
"tickSize": "0.00010000"
},
{
"filterType": "PERCENT_PRICE",
"multiplierUp": "5",
"multiplierDown": "0.2",
"avgPriceMins": 5
},
{
"filterType": "LOT_SIZE",
"minQty": "1.00000000",
"maxQty": "90000000.00000000",
"stepSize": "1.00000000"
},
{
"filterType": "MIN_NOTIONAL",
"minNotional": "10.00000000",
"applyToMarket": true,
"avgPriceMins": 5
},
{
"filterType": "ICEBERG_PARTS",
"limit": 10
},
{
"filterType": "MARKET_LOT_SIZE",
"minQty": "0.00000000",
"maxQty": "904859.10069444",
"stepSize": "0.00000000"
},
{
"filterType": "MAX_NUM_ORDERS",
"maxNumOrders": 200
},
{
"filterType": "MAX_NUM_ALGO_ORDERS",
"maxNumAlgoOrders": 5
}
],
"permissions": [
"SPOT"
]
}

更具体地说,如何从 :

中提取 1.00000000
{
"filterType": "LOT_SIZE",
"minQty": "1.00000000",
"maxQty": "90000000.00000000",
"stepSize": "1.00000000"
}

这是我写的:

public class ParseJson {

    public static void main(String[] args) {

        try {
            URL url = new URL("https://api.binance.com/api/v3/exchangeInfo");
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("GET");
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer content = new StringBuffer();
            while ((inputLine = in.readLine()) != null) {
                content.append(inputLine);
            }
            in.close();

            final String jsonString = content.toString();
            List<Object> dataObject = JsonPath.parse(jsonString).read("symbols");
            dataObject.forEach(x -> {
                        if (x.toString().toUpperCase().contains("TRXEUR")) {
                            List<Object> lo = JsonPath.parse(x.toString()).read("symbol");

                        }
                    }

            );
        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}

哪个 returns :

20:52:10.428 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $['symbols']
20:52:10.469 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $['symbol']
Exception in thread "main" com.jayway.jsonpath.PathNotFoundException: No results for path: $['symbol']
    at com.jayway.jsonpath.internal.path.EvaluationContextImpl.getValue(EvaluationContextImpl.java:133)
    at com.jayway.jsonpath.JsonPath.read(JsonPath.java:187)
    at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:102)
    at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:89)
    at com.reactive.api.scenarios.ParseJson.lambda$main[=14=](ParseJson.java:37)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
    at com.reactive.api.scenarios.ParseJson.main(ParseJson.java:34)

Process finished with exit code 1

我可以访问符号 TRXEUR 并且 symbols 被解析但是如何从 :

中提取 1.00000000
{
"filterType": "LOT_SIZE",
"minQty": "1.00000000",
"maxQty": "90000000.00000000",
"stepSize": "1.00000000"
}

?

我可能不需要在 return 类型(例如 List>)上转换为 Object 并使用 Map 代替,但这有效:

import com.jayway.jsonpath.JsonPath;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;

public class ParseJson {

    public static void main(String[] args) {

        try {
            URL url = new URL("https://api.binance.com/api/v3/exchangeInfo");
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("GET");
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer content = new StringBuffer();
            while ((inputLine = in.readLine()) != null) {
                content.append(inputLine);
            }
            in.close();

            final String jsonString = content.toString();
            List<Map<String, Object>> items = JsonPath.parse(jsonString).read("symbols");
            items.forEach(m -> {
                if (m.get("symbol").toString().toUpperCase().equalsIgnoreCase("BTCEUR")) {
                    List<Map<String, Object>> m3 = (List<Map<String, Object>>) m.get("filters");
                    m3.forEach(m2 -> {
                        if (m2.get("filterType").toString().equalsIgnoreCase("LOT_SIZE")) {
                            System.out.println("Stepsize " + m2.get("stepSize"));
                        }
                    });
                }
            });

        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}

打印:

22:47:25.070 [main] DEBUG com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $['symbols']
Stepsize 0.00000100

来自https://jsonpath.herokuapp.com/

$.filters[?(@.filterType=='LOT_SIZE')].stepSize

你的来源问题:

Object read = JsonPath.read(jsonString, "$.filters[?(@.filterType=='LOT_SIZE')].stepSize");

JSON 来自“https://api.binance.com/api/v3/exchangeInfo”:

Object read = JsonPath.read(jsonString, "$.symbols[?(@.symbol=='BTCEUR')].filters[?(@.filterType=='LOT_SIZE')].stepSize");

如果您仍想使用流,您的第二个泛型是 Object,因此我们确实需要明确地转换 (List>):

String stepSize = items
        .stream()
        .filter(map -> "BTCEUR".equalsIgnoreCase(map.get("symbol").toString()))
        .map(map -> (List<Map<String, Object>>) map.get("filters"))
        .findFirst()
        .orElseThrow()
        .stream()
        .filter(map -> "LOT_SIZE".equalsIgnoreCase(map.get("filterType").toString()))
        .findFirst()
        .orElseThrow()
        .get("stepSize")
        .toString();

System.out.println(stepSize);

您的工作是找到 stepSize 的值,其中符号值为 TRXEUR,filterType 值为 LOT_SIZE。但是如果用Java来做,代码会很长很复杂。

建议您使用 SPL,一个 open-source Java 包。编码真的很容易,你只需要一行:

A
1 =json(httpfile("https://api.binance.com/api/v3/exchangeInfo").read()).
symbols.select(symbol=="TRXEUR").filters.select(~.filterType=="LOT_SIZE").stepSize

SPL 提供 JDBC 驱动程序供 Java 调用。只需将上述 SPL 脚本存储为 getvalue.splx 并在调用存储过程时在 Java 应用程序中调用它:

…
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
st = con.prepareCall("call getvalue()");
st.execute();
…