2014-10-20 117 views

回答

1

您可以註冊custom string deserialiser基於這將在deserialisation後插值變量的默認。

但是,正如在評論中指出的那樣,這對於諸如文件和URL之類的非字符串類型不起作用。更好的想法是通過傳遞定製的JsonFactory來覆蓋JsonParsergetText()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 
+0

如果我想反序列化'String',但如何應用在每個解串器型的轉變他的解決方案僅適用(即路徑)?我想我必須創建一個'JsonParser'來覆蓋'getText'或'getValusAsString'? – 2014-10-29 10:41:14

+0

@gulecroc好點!我已經用你的建議更新了我的答案。 – 2014-10-29 11:51:08

+0

聽起來不錯!我被重寫了'JsonParser',不知道'JsonParserDelegate'!抱歉沒有足夠的聲望投票了...所以+1 – 2014-10-29 13:08:23