如何在从杰克逊中的字符串构造 JsonNode 时更改其值

我有一个 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 {

            ...

        }


在这种情况下,当调用 readTree 方法或未调用方法时,我无法在创建 JsonNode 本身时更改值。此外,json 字符串也可以不同。基本上,我想从字符串构造一个 JsonNode。因此,在这里绑定到特定的模式/bean 不是一个好的选择。如何解决这个问题?蒂亚getCurrentValuegetValueAsString


烙印99
浏览 147回答 2
2回答

jeck猫

编辑:和 之间有细微的区别。同时能够区分和与2.7.*2.9.*2.9.*doublefloatgetDoubleValue()getFloatValue()而是只使用2.7.*getDoubleValue()即使是代币。因此,您需要决定是否要保持逆向兼容性。ID_NUMBER_FLOAT您也可以覆盖两者,就像我在这里所做的那样。这就是您的定制所需的全部内容MyParserstatic 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}您的代码看起来很好,并且已经过测试并;)

慕田峪9158850

您是否真的确定,关于关注点分离,在解析的数据中混合解析和更改是一个好主意?如果您仍然想这样做,则可以使用自定义反序列化程序,并按照所需的方式处理所需的字段名称和类型,例如:class CustomDeserializer extends StdDeserializer<Entity> {&nbsp; &nbsp; public CustomDeserializer(Class<Entity> t) {&nbsp; &nbsp; &nbsp; &nbsp; super(t);&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public Entity deserialize(JsonParser jp, DeserializationContext dc) throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; String name = null;&nbsp; &nbsp; &nbsp; &nbsp; float price = 0;&nbsp; &nbsp; &nbsp; &nbsp; JsonToken currentToken = null;&nbsp; &nbsp; &nbsp; &nbsp; while ((currentToken = jp.nextValue()) != null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch (currentToken) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case VALUE_STRING:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch (jp.getCurrentName()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "name":&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name = jp.getText() + "-3"; // change this text to whatever you want;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "price":&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; price = Float.parseFloat(jp.getText()); // parse&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return new Entity(name, price);&nbsp; &nbsp; }}注册自定义反序列化程序后,它可以在您想要的任何对象映射器上运行:&nbsp; &nbsp; @Test&nbsp; &nbsp; public void customDeserialization() throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; // given&nbsp; &nbsp; &nbsp; &nbsp; ObjectMapper mapper = new ObjectMapper();&nbsp; &nbsp; &nbsp; &nbsp; SimpleModule module = new SimpleModule();&nbsp; &nbsp; &nbsp; &nbsp; module.addDeserializer(Entity.class, new CustomDeserializer(Entity.class));&nbsp; &nbsp; &nbsp; &nbsp; mapper.registerModule(module);&nbsp; &nbsp; &nbsp; &nbsp; // when&nbsp; &nbsp; &nbsp; &nbsp; Entity entity = mapper.readValue("{\"name\":\"xyz\",\"price\":\"90.00\"}", Entity.class);&nbsp; &nbsp; &nbsp; &nbsp; // then&nbsp; &nbsp; &nbsp; &nbsp; assertThat(entity.getName()).isEqualTo("xyz-3");&nbsp; &nbsp; &nbsp; &nbsp; assertThat(entity.getPrice()).isEqualTo(90f);&nbsp; &nbsp; }
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java