如何使用Jackson从jsonToken获取原始json值

6ju8rftf  于 2022-11-09  发布在  其他
关注(0)|答案(2)|浏览(122)

我有json,我需要从它的一个节点中获取原始的json,它包含所有原始字符,包括换行符和空格。例如:

{
    "auth": {
        "hash": "f9d876df71dfc72810a497dc38d1c1f467c720d8171da5e2c974647978c645ae"
    },
    "request": {
        "p1": 1885,
        "p2": [
            "test"
        ],
        "p3": {
            "in": 10
        }
    }
}

我需要使用原始json以String形式获取请求节点的值,如下所示:

{
        "p1": 1885,
        "p2": [
            "test"
        ],
        "p3": {
            "in": 10
        }
    }

我试试:

String rawRequest = null;

    JsonFactory jsonFactory = new JsonFactory();
    JsonParser jsonParser = jsonFactory.createParser(json)
    JsonToken jsonToken = jsonParser.nextToken();
    while (jsonToken != null) {
        if (jsonToken == JsonToken.FIELD_NAME) {
            String fieldName = jsonParser.getCurrentName();
            if ("request".equals(fieldName)) {
                jsonParser.nextToken();
                rawRequest = jsonParser.getValueAsString();
                break;
            }
        }
        jsonToken = jsonParser.nextToken();
    }

但是它不工作。我该怎么做呢?在极端的情况下,甚至可以使用第三方库。

eanckbw9

eanckbw91#

我能做的解决方案如下:

private String getRawRequest(String json) throws IOException {
    String rawRequest = null;
    JsonFactory jsonFactory = new JsonFactory();
    JsonParser jsonParser = jsonFactory.createParser(json);
    JsonToken jsonToken = jsonParser.nextToken();

    while (jsonToken != null) {
        if (jsonToken == JsonToken.FIELD_NAME) {
            String fieldName = jsonParser.getCurrentName();
            if ("request".equals(fieldName)) {
                jsonParser.nextToken();

                int startIndex = findCurrentTokenIndex(jsonParser, json);
                jsonParser.skipChildren();
                int endIndex = findCurrentTokenIndex(jsonParser, json);

                rawRequest = json.substring(startIndex - 1, endIndex + 1);
                break;
            }
        }
        jsonToken = jsonParser.nextToken();
    }

    return rawRequest;
}

private int findCurrentTokenIndex(JsonParser jsonParser, String json) throws IOException {
    JsonLocation startTokenLocation = jsonParser.getTokenLocation();
    int lineNr = startTokenLocation.getLineNr();
    int columnNr = startTokenLocation.getColumnNr();
    return findIndex(json, lineNr, columnNr);
}

private int findIndex(String json, Integer line, Integer position) throws IOException {
    byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes)));
    int index = 0;
    int currentLine = 0;
    while (true) {
        String lineData = bufferedReader.readLine();
        currentLine++;
        if (currentLine == line) {
            index += position;
            break;
        } else {
            index += lineData.length() + 1; //line break (without carriage return)
        }
    }
    return index;
}

看起来效率很低,但我不想写自己的解析器。缺点是位置搜索。在添加回车和换行符的情况下。

1wnzp6jl

1wnzp6jl2#

您可以使用Jackson的ObjectMapper来读取原始json,然后提取请求属性,如

String rawJson = "" +
"{\n" +
"    \"auth\": {\n" +
"        \"hash\": \"f9d876df71dfc72810a497dc38d1c1f467c720d8171da5e2c974647978c645ae\"\n" +
"    },\n" +
"    \"request\": {\n" +
"        \"p1\": 1885,\n" +
"        \"p2\": [\n" +
"            \"test\"\n" +
"        ],\n" +
"        \"p3\": {\n" +
"            \"in\": 10\n" +
"        }\n" +
"    }\n" +
"}\n";

ObjectMapper objectMapper = new ObjectMapper();
JsonNode node = objectMapper.readTree(rawJson);
String rawRequest = node.get("request").toString();
System.out.println(rawRequest);

要使其正常工作,您需要jackson-databindjackson-annotations依赖项。

相关问题