2013-02-20 57 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