【发布时间】:2014-12-15 14:21:18
【问题描述】:
如何自定义 Jackson 以反序列化包含 ${token} 的值?
这是我想从Apache Commons Configuration variable interpolation 添加的功能示例:
{
"file" = "${sys:user.home}/path/to/my_file"
}
【问题讨论】:
标签: java json jackson token interpolation
如何自定义 Jackson 以反序列化包含 ${token} 的值?
这是我想从Apache Commons Configuration variable interpolation 添加的功能示例:
{
"file" = "${sys:user.home}/path/to/my_file"
}
【问题讨论】:
标签: java json jackson token interpolation
您可以根据默认值注册custom string deserialiser,它将在反序列化后插入变量。
但是,正如 cmets 中所指出的,这不适用于非字符串类型,例如文件和 URL。更好的办法是通过传递自定义的JsonFactory 来覆盖JsonParser 的getText() 和getValueAsString() 方法。
这是一个例子:
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
【讨论】:
String 时才有效,但是如何对每个反序列化器类型(即路径)应用转换?我想我必须创建一个 JsonParser 来覆盖 getText 或 getValusAsString?
JsonParser 卡住了,不知道JsonParserDelegate!很抱歉没有足够的声誉来投票......所以+1