杰克逊用变量插值反序列化 [英] Jackson deserialize with variable interpolation

查看:234
本文介绍了杰克逊用变量插值反序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何自定义Jackson反序列化包含 $ {token} 的值?

How to custom Jackson to deserialize a value that contains a ${token} ?

这是一个我要在 Apache Commons中添加的功能实例示例配置变量插值

{
    "file" = "${sys:user.home}/path/to/my_file"
}


推荐答案

您可以根据默认情况注册自定义字符串反序列化程序,这将在反序列化后插入变量。

You can register a custom string deserialiser based on the default which would interpolate the variables after the deserialisation.

但是,正如评论中指出的那样,这对于非String类型(如文件和URL)不起作用。更好的想法是覆盖 JsonParser的 getText() getValueAsString()方法传递自定义 JsonFactory

But, as was pointed out in the comments, that would not work for the non-String types such as File and URLs. The better idea is to override the getText() and getValueAsString() methods of the JsonParser by passing a custom JsonFactory.

以下是一个例子:

public class JacksonInterpolateString {
    static final String JSON = "{ \"file\":\"${sys:user.home}/path/to/my_file\" }";

    public static class Bean {
        public File file;

        @Override
        public String toString() {
            return file.toString();
        }
    }

    private static class MyJsonParser extends JsonParserDelegate {

        public MyJsonParser(final JsonParser d) {
            super(d);
        }

        @Override
        public String getText() throws IOException {
            final String value = super.getText();
            if (value != null) {
                return interpolateString(value);
            }
            return value;
        }

        @Override
        public String getValueAsString() throws IOException {
            return getValueAsString(null);
        }

        @Override
        public String getValueAsString(final String defaultValue) throws IOException {
            final String value = super.getValueAsString(defaultValue);
            if (value != null) {
                return interpolateString(value);
            }
            return null;
        }
    }

    private static class MyMappingJsonFactory extends MappingJsonFactory {
        @Override
        protected JsonParser _createParser(
                final char[] data,
                final int offset,
                final int len,
                final IOContext ctxt,
                final boolean recyclable)
                throws IOException {
            return new MyJsonParser(super._createParser(data, offset, len, ctxt, recyclable));
        }

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

    }

    private static String interpolateString(final String value) {
        return value.replace("${sys:user.home}", "/home/user");
    }

    public static void main(String[] args) throws IOException {
        final JsonFactory factory = new MyMappingJsonFactory();
        final ObjectMapper mapper = new ObjectMapper(factory);
        System.out.println(mapper.readValue(JSON, Map.class));
        System.out.println(mapper.readValue(JSON, Bean.class));
    }

}

输出:

{file=/home/user/path/to/my_file}
/home/user/path/to/my_file

这篇关于杰克逊用变量插值反序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆