简体   繁体   中英

Parsing nested JSON nodes to POJOs using Google Http Java Client

For example I have a response with the following JSON:

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

And I want to parse it to the following object:

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

How to skip the response node?

I use Google Http Java Client and it will be good if someone will answer how to do it there. How will this lines have changed?

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

You can now implement this in one step:

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

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

I do not know the Google Http Java Client, but if you can access the Jackson ObjectMapper you could do the following:

1.) Enable root unwrapping:

objectMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);

2.) Add annotation to User.class:

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

I hope you can use this approach.

Edit: I dug through the google-http-java-client API and have come to the conclusion that you cannot access the ObjectMapper directly. In order to use the full power of Jackson you would have to write your own implementation of JsonObjectParser to wrap a 'real' Jackson parser. Sorry about that, maybe someone else could come up with a better solution.

I didn't find a native way (for this library) to solve my task. As a result I solved this problem by extending the functionality of JsonObjectParser . It entails expanding of the JacksonFactory , but it's a final class, so I used aggregation.

I wrote the following classes:

  • 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); } } 

So, for example from my question, the result parsing code will be the following:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM