如何从 JsonParser 获取底层字符串 (Jackson Json)

2022-09-01 17:19:47

浏览文档和源代码,我没有看到一个明确的方法来做到这一点。好奇我是否错过了什么。

假设我从服务器响应中收到输入流。我从这个输入流创建了一个JsonParser。预计服务器响应是包含有效 JSON 的文本,例如:

{"iamValidJson":"yay"}

但是,如果响应最终是无效的 JSON 或根本不是 JSON,例如:

Some text that is not JSON

JsonParser 最终将引发异常。在这种情况下,我希望能够从JsonParser中提取底层无效文本“”,以便它可以用于其他目的。Some text that is not JSON

我无法将其从 InputStream 中拉出,因为它不支持重置,并且 JsonParser 的创建会消耗它。

有没有办法做到这一点?


答案 1

如果你有,那么你可以使用.JsonParserjsonParser.readValueAsTree().toString()

但是,这可能要求正在解析的 JSON 确实是有效的 JSON。


答案 2

我遇到过这样的情况:我使用的是自定义反序列化程序,但我希望默认的反序列化程序完成大部分工作,然后使用 SAME json 执行一些额外的自定义工作。但是,在默认的反序列化程序完成其工作后,JsonParser 对象的当前位置超出了我需要的 json 文本。所以我遇到了和你一样的问题:如何访问底层的json字符串。

您可以使用 来访问基础 json 源。用于在 json 源中查找当前位置。JsonParser.getCurrentLocation.getSourceRef()JsonParser.getCurrentLocation().getCharOffset()

这是我使用的解决方案:

public class WalkStepDeserializer extends StdDeserializer<WalkStep> implements
    ResolvableDeserializer {

    // constructor, logger, and ResolvableDeserializer methods not shown

    @Override
    public MyObj deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
            JsonProcessingException {
        MyObj myObj = null;

        JsonLocation startLocation = jp.getCurrentLocation();
        long charOffsetStart = startLocation.getCharOffset();

        try {
            myObj = (MyObj) defaultDeserializer.deserialize(jp, ctxt);
        } catch (UnrecognizedPropertyException e) {
            logger.info(e.getMessage());
        }

        JsonLocation endLocation = jp.getCurrentLocation();
        long charOffsetEnd = endLocation.getCharOffset();
        String jsonSubString = endLocation.getSourceRef().toString().substring((int)charOffsetStart - 1, (int)charOffsetEnd);
        logger.info(strWalkStep);

        // Special logic - use JsonLocation.getSourceRef() to get and use the entire Json
        // string for further processing

        return myObj;
    }
}

有关在自定义反序列化程序中使用默认反序列化程序的信息,请参阅如何从 Jackson 中的自定义反序列化程序调用默认反序列化程序