2013-02-20 15 views
2

例如,我有以下的JSON響應的POJO:解析嵌套的JSON節點使用谷歌的Http Java客戶端

{ 
    response: { 
     id: 20, 
     name: Stas 
    } 
} 

而且我想它解析爲以下對象:

class User { 
    private int id; 
    private String name; 
} 

如何跳過響應節點?

我使用谷歌Http Java客戶端,如果有人會回答如何在那裏做它會很好。 這條線將如何改變?

request.setParser(new JacksonFactory().createJsonObjectParser()); 
return request.execute().parseAs(getResultType()); 

回答

2

我不知道谷歌的Http Java客戶端,但如果你能訪問傑克遜ObjectMapper你可以做到以下幾點:

1)Enable根解包:

objectMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE); 

2 )將annotation添加到User.class中:

@JsonRootName("response") 
class User { 
    … 
} 

我希望你可以使用這種方法。

編輯:我挖通了google-http-java-client API,並得出結論,你不能直接訪問ObjectMapper。爲了充分利用傑克遜的力量,你必須編寫自己的JsonObjectParser實現來包裝一個「真正的」傑克遜解析器。對不起,可能有人會想出更好的解決方案。

2

我沒有找到一種本地方式(對於這個庫)來解決我的任務。因此我通過擴展JsonObjectParser的功能來解決這個問題。它需要擴大JacksonFactory,但它是最後一堂課,所以我使用了聚合。

我寫了下面的類:

  • JacksonFilteringFactory

    import com.google.api.client.json.JsonObjectParser; 
    import com.google.api.client.json.jackson2.JacksonFactory; 
    
    public class JacksonFilteringFactory { 
        private final JacksonFactory factory = new JacksonFactory(); 
    
        public JsonObjectParser createJsonObjectParser(String filteringNode) { 
         return new FilteringJsonObjectParser(factory, filteringNode); 
        } 
    } 
    
  • FilteringJsonObjectParser

    import java.io.ByteArrayInputStream; 
    import java.io.IOException; 
    import java.io.InputStream; 
    import java.lang.reflect.Type; 
    import java.nio.charset.Charset; 
    
    import org.json.JSONException; 
    import org.json.JSONObject; 
    import org.json.JSONTokener; 
    
    import com.google.api.client.json.JsonFactory; 
    import com.google.api.client.json.JsonObjectParser; 
    import com.vkredmessenger.AppController; 
    import com.vkredmessenger.util.StringUtils; 
    
    public class FilteringJsonObjectParser extends JsonObjectParser { 
    
        private String mFilteringNode; 
    
        public FilteringJsonObjectParser(JsonFactory jsonFactory, 
          String filteringNode) { 
    
         super(jsonFactory); 
    
         mFilteringNode = filteringNode; 
        } 
    
        @Override 
        public Object parseAndClose(InputStream in, 
          Charset charset, Type dataType) 
           throws IOException { 
    
         String originalResponse = 
           StringUtils.convertStreamToString(in, charset); 
    
         String response = null; 
    
         try { 
          JSONTokener tokener = new JSONTokener(originalResponse); 
          JSONObject originalResponseObject = 
            (JSONObject) tokener.nextValue(); 
    
          JSONObject responseObject = 
            originalResponseObject.getJSONObject(mFilteringNode); 
          response = responseObject.toString(); 
    
         } catch (JSONException e) { 
          e.printStackTrace(); 
         } 
    
         InputStream filteredIn = 
           new ByteArrayInputStream(response.getBytes(charset)); 
    
         return super.parseAndClose(filteredIn, charset, dataType); 
        } 
    } 
    

所以,例如我的問題,結果解析的源代碼G代碼如下:

request.setParser(new JacksonFilteringFactory().createJsonObjectParser("response")); 
return request.execute().parseAs(getResultType()); 
3

您可以一步就實現這個:

new JsonObjectParser.Builder(jsonFactory) 
    .setWrapperKeys(Arrays.asList("response")) 
    .build() 

http://javadoc.google-http-java-client.googlecode.com/hg/1.15.0-rc/index.html

+0

可以解釋這一塊嗎?什麼意思是「一步到位」 – seb 2014-03-23 22:29:22

+0

目前爲止最好的答案,但是javadoc的鏈接已經死了。 [這裏](https://google.github.io/google-http-java-client/releases/1.21.0/javadoc/index.html)是最近一個的鏈接 – Blablablabli 2016-11-17 15:38:22