2

たとえば、次の 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());
4

3 に答える 3

2

Google Http Javaクライアントはわかりませんが、Jackson ObjectMapperにアクセスできる場合は、次のようにすることができます。

1.)ルートアンラッピングを有効にします。

objectMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);

2.)User.classに注釈を追加します。

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

このアプローチを使用できることを願っています。

編集:私はgoogle-http-java-client APIを掘り下げて、ObjectMapperに直接アクセスできないという結論に達しました。Jacksonの全機能を使用するには、「実際の」JacksonパーサーをラップするJsonObjectParserの独自の実装を作成する必要があります。申し訳ありませんが、他の誰かがより良い解決策を考え出す可能性があります。

于 2013-02-20T09:15:36.770 に答える
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);
        }
    }
    

したがって、たとえば私の質問から、結果の解析コードは次のようになります。

request.setParser(new JacksonFilteringFactory().createJsonObjectParser("response"));
return request.execute().parseAs(getResultType());
于 2013-02-20T18:03:40.360 に答える