ジャクソンの文字列からそれを構築しながら、JsonNodeの値を変更する方法

dks551:

私は、JSON文字列を持っていると私はジャクソンライブラリを使用して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, int offset, int len, IOContext ctxt, boolean recyclable)
                    throws IOException {
                return new MyParser(super._createParser(data, offset, len, 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>
LppEdd:

編集:との間に微妙な違いがある2.7.*とは2.9.*
一方で2.9.*区別することができますdoublefloatして

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;
    }
}

出力: {"name":"xyz-3","price":90.09}

あなたのコードは罰金だ、それがテストされ、働いています;)

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=210701&siteId=1