Разбор вложенных узлов JSON в POJO с помощью Google Http Java Client

Например, у меня есть ответ со следующим JSON:

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

И я хочу разобрать его на следующий объект:

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

Как пропустить узел ответа?

Я использую Google Http Java Client, и будет хорошо, если кто-нибудь ответит, как это сделать. Как эти линии изменились?

request.setParser(new JacksonFactory().createJsonObjectParser());
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

Я не нашел родной способ (для этой библиотеки) решить мою задачу. В результате я решил эту проблему, расширив функциональность 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);
        }
    }
    

Так, например, из моего вопроса, результат анализа кода будет следующим:

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

Я не знаю Java Http-клиент Google, но если вы можете получить доступ к Jackson ObjectMapper, вы можете сделать следующее:

1.) Включить распаковку корня:

objectMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);

2.) Добавить аннотацию к User.class:

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

Я надеюсь, что вы можете использовать этот подход.

Изменить: я копался в API google-http-java-client и пришел к выводу, что вы не можете получить прямой доступ к ObjectMapper. Чтобы использовать всю мощь Джексона, вам нужно написать собственную реализацию JsonObjectParser, чтобы обернуть "настоящий" парсер Джексона. Извините за это, может быть, кто-то еще может найти лучшее решение.

Другие вопросы по тегам