首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不通过ObjectCodec时,如何在JsonParser上设置ObjectMapper?

不通过ObjectCodec时,如何在JsonParser上设置ObjectMapper?
EN

Stack Overflow用户
提问于 2014-04-05 02:33:31
回答 2查看 13.9K关注 0票数 3

注意:这里使用的是Jackson 2.3.2

为了满足我的一个项目的需要,我编写了一个自定义的JsonParser,它记录了一个Map,其中键是JsonPointers,值是Integers (指针指向的行号)。

这个类被命名为LineRecorderJsonParser。它是由一个简单的委托LineRecorderJsonFactory产生的:

代码语言:javascript
复制
public final class LineRecorderJsonFactory
    extends JsonFactory
{
    @Override
    protected JsonParser _createParser(final InputStream in,
        final IOContext ctxt)
        throws IOException, JsonParseException
    {
        final JsonParser parser = super._createParser(in, ctxt);
        return new LineRecorderJsonParser(parser);
    }

    @Override
    protected JsonParser _createParser(final Reader r, final IOContext ctxt)
        throws IOException, JsonParseException
    {
        final JsonParser parser = super._createParser(r, ctxt);
        return new LineRecorderJsonParser(parser);
    }

    @Override
    protected JsonParser _createParser(final byte[] data, final int offset,
        final int len, final IOContext ctxt)
        throws IOException, JsonParseException
    {
        final JsonParser parser = super._createParser(data, offset, len, ctxt);
        return new LineRecorderJsonParser(parser);
    }
}

我已经使用以下代码测试了代码的工作情况:

代码语言:javascript
复制
public static void main(final String... args)
    throws IOException
{
    final JsonFactory factory = new LineRecorderJsonFactory();
    final ObjectMapper mapper = new ObjectMapper(factory);
    final Closer closer = Closer.create();
    final InputStream in;

    try {
        in = closer.register(LineTesting.class.getResourceAsStream
            ("/testfile.json"));
        mapper.readTree(in);
    } finally {
        closer.close();
    }
}

但现在我想测试它;所以我编写了以下测试代码:

代码语言:javascript
复制
public final class LineRecorderJsonParserTest
{
    private static final String INCORRECT_LINE_INFO
        = "generated line info is incorrect; expected: %s, actual: %s";

    private JsonFactory factory;
    private ObjectMapper mapper;

    @BeforeMethod
    public void initFactory()
    {
        factory = new LineRecorderJsonFactory();
        mapper = new ObjectMapper();
    }

    @DataProvider
    public Iterator<Object[]> getLineData()
    {
        final List<Object[]> list = Lists.newArrayList();

        list.add(new Object[] { "1" });
        return list.iterator();
    }

    @Test(dataProvider = "getLineData")
    public void lineNumbersAreCorrectlyReported(final String subdir)
        throws IOException
    {
        final String basePath = "/parser/" + subdir + '/';
        final Closer closer = Closer.create();
        final TypeReference<Map<JsonPointer, Integer>> typeRef
            = new TypeReference<Map<JsonPointer, Integer>>() {};

        final InputStream input, lines;
        final Map<JsonPointer, Integer> actual, expected;
        final LineRecorderJsonParser parser;

        try {
            input = closer.register(inputFrom(basePath + "input.json"));
            lines = closer.register(inputFrom(basePath + "lines.json"));

            expected = mapper.readValue(lines, typeRef);

            parser = (LineRecorderJsonParser) factory.createParser(input);
            //parser.setCodec(factory.getCodec()); // Doesn't change anything...
            parser.readValueAsTree(); // FAILS HERE
            actual = parser.getLineInfo();

            assertEquals(actual, expected,
                String.format(INCORRECT_LINE_INFO, expected, actual));
        } catch (IOException e) {
            throw closer.rethrow(e);
        } finally {
            closer.close();
        }
    }

    private static InputStream inputFrom(final String path)
    {
        return LineRecorderJsonParserTest.class.getResourceAsStream(path);
    }
}

不幸的是,这不起作用。我得到了以下异常:

代码语言:javascript
复制
java.lang.IllegalStateException: No ObjectCodec defined for the parser, can not deserialize JSON into JsonNode tree
    at com.fasterxml.jackson.core.JsonParser.readValueAsTree(JsonParser.java:1507)
    at com.fasterxml.jackson.core.util.JsonParserDelegate.readValueAsTree(JsonParserDelegate.java:371)
    at com.github.fge.jackson.parse.LineRecorderJsonParserTest.lineNumbersAreCorrectlyReported(LineRecorderJsonParserTest.java:84)

即使当我(尝试和)自己设置ObjectCodec (参见代码)时,我也会得到这个异常...

我做错了什么?我如何测试这个类,因为当您直接使用ObjectMapper读取时,您没有机会获取底层解析器?

EN

回答 2

Stack Overflow用户

发布于 2014-04-05 03:40:35

或者,JsonFactory.setCodec(mapper)

票数 11
EN

Stack Overflow用户

发布于 2014-04-05 02:48:31

嗯,在我问完这个问题后不到几分钟,我就知道怎么做了……如果它对其他人有用,我会对自己负责的。

首先,我的JsonFactory.getCodec()返回了null;如果你尝试给它一个空的编解码器,JsonParser不会对你大喊大叫。

其次,ObjectMapper扩展了ObjectCodecObjectCodec has a method to read a tree (实际上,它包含了您在ObjectMapper上习惯使用的所有方法)。

因此,将代码更改为以下代码是可行的:

代码语言:javascript
复制
parser = (LineRecorderJsonParser) factory.createParser(input);
mapper.readTree(parser);
actual = parser.getLineInfo();
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22870488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档