java-如何在Jackson的字符串中构造JsonNode时更改其值

前端之家收集整理的这篇文章主要介绍了java-如何在Jackson的字符串中构造JsonNode时更改其值 前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我有一个JSON字符串,我想在使用Jackson库构造JsonNode时更改值.
例如:-

input: {"name":"xyz","price":"90.00"}
output:{"name":"xyz-3","price":90.90}

我创建了自己的JsonFactory并通过了自己的解析器.但我只能更改键,而不能更改与键关联的值.

码:

private static ObjectMapper create() {
        ObjectMapper objectMapper = new ObjectMapper(new JsonFactory() {
            @Override
            protected JsonParser _createParser(byte[] data,int offset,int len,IOContext ctxt) throws IOException {
                return new MyParser(super._createParser(data,offset,len,ctxt));
            }

            @Override
            protected JsonParser _createParser(InputStream in,IOContext ctxt) throws IOException {
                return new MyParser(super._createParser(in,ctxt));
            }

            @Override
            protected JsonParser _createParser(Reader r,IOContext ctxt) throws IOException {
                return new MyParser(super._createParser(r,ctxt));
            }

            @Override
            protected JsonParser _createParser(char[] data,IOContext ctxt,boolean recyclable)
                    throws IOException {
                return new MyParser(super._createParser(data,ctxt,recyclable));
            }
        });

private static final class MyParser extends JsonParserDelegate {

        private MyParser(JsonParser d) {
            super(d);
        }

        @Override
        public String getCurrentName() throws IOException,JsonParseException {
            ....
        }

        @Override
        public String getText() throws IOException,JsonParseException {
           ...
        }

        @Override
        public Object getCurrentValue() {
            ...
        }


        @Override
        public String getValueAsString() throws IOException {
            ...
        }

        @Override
        public String getValueAsString(String defaultValue) throws IOException {
            ...
        }
    }

下面是从字符串构造JsonNode的代码.

mapper.readTree(jsonStr);

在这种情况下,当调用readTree方法时,不会调用getCurrentValue或getValueAsString方法,因此在创建JsonNode本身时,我无法更改该值.
json字符串也可以不同.基本上我想从字符串构造一个JsonNode.因此,在这里绑定特定的架构/ bean不是一个好选择.
如何解决呢? TIA

为版本2.7.4添加更新的代码:-

static class MyParser extends JsonParserDelegate {
        MyParser(final JsonParser delegate) {
            super(delegate);
        }

        @Override
        public String getText() throws IOException {
            final String text = super.getText();

            if ("name".equals(getCurrentName())) {
                return text + "-3";
            }

            return text;
        }

        @Override
        public JsonToken nextToken() throws IOException {
            if ("price".equals(getCurrentName())) {
                // Advance token anyway
                super.nextToken();
                return JsonToken.VALUE_NUMBER_FLOAT;
            }

            return super.nextToken();
        }

        @Override
        public int getCurrentTokenId() {
            try {
                if ("price".equals(getCurrentName())) {
                    return JsonTokenId.ID_NUMBER_FLOAT;
                }
            } catch (final IOException e) {
                //
            }

            return super.getCurrentTokenId();
        }

        @Override
        public NumberType getNumberType() throws IOException {
            if ("price".equals(getCurrentName())) {
                return NumberType.FLOAT;
            }

            return super.getNumberType();
        }

        @Override
        public float getFloatValue() throws IOException {
            return Float.parseFloat(getValueAsString("0")) + 0.09F;
        }

        @Override
        public double getDoubleValue() throws IOException {
            return Double.parseDouble(getValueAsString("0")) + 0.09D;
        }


    }

pom.xml:-

         <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-yaml</artifactId>
            <version>2.8.7</version>
            <!--<scope>test</scope>-->
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>2.8.7</version>
        </dependency>
最佳答案
编辑:2.7.*和2.9.*之间有细微的差别.
2.9.*可以区分double和float

getDoubleValue()
getFloatValue()

而是2.7.*仅使用

getDoubleValue()

即使是ID_NUMBER_FLOAT令牌.
因此,您需要确定是否要保持回溯兼容性.

您也可以像在这里一样覆盖这两者.

这就是您自定义MyParser所需的一切

static class MyParser extends JsonParserDelegate {
    MyParser(final JsonParser delegate) {
        super(delegate);
    }

    @Override
    public String getText() throws IOException {
        final String text = super.getText();

        if ("name".equals(getCurrentName())) {
            return text + "-3";
        }

        return text;
    }

    @Override
    public JsonToken nextToken() throws IOException {
        if ("price".equals(getCurrentName())) {
            // Advance token anyway
            super.nextToken();
            return JsonToken.VALUE_NUMBER_FLOAT;
        }

        return super.nextToken();
    }

    @Override
    public int getCurrentTokenId() {
        try {
            if ("price".equals(getCurrentName())) {
                return JsonTokenId.ID_NUMBER_FLOAT;
            }
        } catch (final IOException e) {
            //
        }

        return super.getCurrentTokenId();
    }

    @Override
    public NumberType getNumberType() throws IOException {
        if ("price".equals(getCurrentName())) {
            return NumberType.FLOAT;
        }

        return super.getNumberType();
    }

    @Override
    public float getFloatValue() throws IOException {
        return Float.parseFloat(getValueAsString("0")) + 0.09F;
    }

    @Override
    public double getDoubleValue() throws IOException {
       return Double.parseDouble(getValueAsString("0")) + 0.09D;
    }
}

输出:{“名称”:“ xyz-3”,“价格”:90.09}

您的代码看起来不错,并且已经过测试并且可以正常工作;)

猜你在找的Java相关文章