2013-03-26 48 views
0

好時機!Jackson:在自定義解串器中獲取任意節點的值

說,有一個json字符串:{id:'a', type:'b', category:'c'},業務邏輯是這樣的,建立一個類別對象,我需要知道類別名稱('c')和類型('b')。很明顯,我需要編寫一個自定義反序列化器(@JsonDeserialize(using = CategoryCustomDeserializer.class)),對於類別,獲取類別名稱很簡單,但我無法弄清楚如何獲取類型的值...我試過這個:jsonParser.getCodec().readTree(jsonParser),但它返回null

請建議正確的方法來做到這一點。

編輯: 這裏是解串器:

public class CategoryNameDeserializer extends JsonDeserializer<Category> { 

    @Override 
    public Category deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { 
     if (jp.getCurrentToken() != JsonToken.END_OBJECT) { 
      String categoryName = jp.getText(); 
      String type = ?????? <------------------------ How to do it 
      return Service.getInstance().getCategory(categoryName, type); 
     } 

     return null; 
    } 
} 
+1

它根本不清楚你需要編寫一個自定義的解串器。事實上,使用Jackson POJO綁定會簡單得多,而忽略額外的不需要的字段。如果您決定不管什麼原因繼續使用自定義反序列化器,那麼您應該能夠獲取類型值,就像獲取類別名稱一樣。您可能希望在問題中包含您當前的解串器代碼。 – Perception 2013-03-26 11:36:53

+0

@Perception,其實我真的需要自定義的反序列化器,因爲在構建Category對象時有一些事情要做。我已經添加了解串器代碼。 – Dmitry 2013-03-26 12:07:43

回答

0

嗯,我找到了答案。這是一種解決方法,但它可行。人們可以用這樣的方法重置解析器:

private JsonParser getResetParser(JsonParser jp) throws IOException { 
    JsonFactory factory = jp.getCodec().getFactory(); 

    StringReader inputSource = (StringReader) jp.getInputSource(); 
    inputSource.reset(); 

    BufferedReader br = new BufferedReader(inputSource); 
    String source = br.readLine(); 

    return factory.createJsonParser(source); 
} 

然後:

private String findTokenText(JsonParser jp, String fieldName) throws IOException { 
    JsonParser parser = getResetParser(jp); 
    while (true) { 
     parser.nextToken(); 
     if (parser.hasCurrentToken()) { 
      switch (parser.getCurrentToken()) { 
       case END_ARRAY: 
       case END_OBJECT: 
       case NOT_AVAILABLE: 
       case START_ARRAY: 
       case START_OBJECT: 
       case VALUE_EMBEDDED_OBJECT: 
       case VALUE_FALSE: 
       case VALUE_NUMBER_FLOAT: 
       case VALUE_NUMBER_INT: 
       case VALUE_TRUE: 
        // do nothing 
        break; 
       case FIELD_NAME: 
        String currentName = parser.getCurrentName(); 
        if (fieldName.equals(currentName)) { 
         parser.nextToken(); 
         return parser.getText(); 
        } 
        break; 
      } 
     } else { 
      return null; 
     } 
    } 

我不明白的是爲什麼儘管執行inputSource.reset();findTokenText方法裏面的代碼jp.getText()(剛剛試了一下在調試模式下)返回「C」,就好像讀卡器沒有復位一樣。 有人可以解釋,爲什麼會發生這種情況?

另一個變種是避免自定義和使用this後的建議。