2
如何自定義Jackson反序列化一個包含${token}
的值?Jackson可變插值反序列化
這裏是我想從Apache Commons Configuration variable interpolation添加functionnality的例子:
{
"file" = "${sys:user.home}/path/to/my_file"
}
如何自定義Jackson反序列化一個包含${token}
的值?Jackson可變插值反序列化
這裏是我想從Apache Commons Configuration variable interpolation添加functionnality的例子:
{
"file" = "${sys:user.home}/path/to/my_file"
}
您可以註冊custom string deserialiser基於這將在deserialisation後插值變量的默認。
但是,正如在評論中指出的那樣,這對於諸如文件和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'? – 2014-10-29 10:41:14
@gulecroc好點!我已經用你的建議更新了我的答案。 – 2014-10-29 11:51:08
聽起來不錯!我被重寫了'JsonParser',不知道'JsonParserDelegate'!抱歉沒有足夠的聲望投票了...所以+1 – 2014-10-29 13:08:23