web-dev-qa-db-ja.com

ボレーを使用してGSONリクエストを行う

次のjson応答があります

{
  "tag": [
    {
      "listing_count": 5,
      "listings": [
        {
          "source": "source1",
          "data": {
            "image": "image1",
            "name": "name1"
          },
          "name": "name1"
        }
      ]
    },
    {
      "listing_count": 5,
      "listings": [
        {
          "source": "source2",
          "data": {
            "image": "imag2",
            "name": "name2"
          },
          "name": "name2"
        }
      ]
    }
  ]
}

GSONリクエスト用に以下のクラスを作成しました。 GSONリクエストを作成し、ボレーリクエストを使用してレスポンスの値を保存するにはどうすればよいですか。 GSONリクエストはどのようにすべきですか?

public class TagList {

ArrayList<Tag> tags;

public static class Tag {
    int listing_count;
    ArrayList<Listings> listings;

    public int getListing_count() {
        return listing_count;
    }

    public void setListing_count(int listing_count) {
        this.listing_count = listing_count;
    }

    public ArrayList<Listings> getListings() {
        return listings;
    }

    public void setListings(ArrayList<Listings> listings) {
        this.listings = listings;
    }

}

public static class Listings {
    String source;
    Data data;
    String name;

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public Data getData() {
        return data;
    }

    public void setData(Data data) {
        this.data = data;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

public static class Data {
    String image;
    String name;

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
11
Abhay Sood

次のようにGsonRequestクラスを作成するだけです( Android Developer Docs から取得)

_public class GsonRequest<T> extends Request<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
private final Listener<T> listener;

/**
 * Make a GET request and return a parsed object from JSON.
 *
 * @param url URL of the request to make
 * @param clazz Relevant class object, for Gson's reflection
 * @param headers Map of request headers
 */
public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
        Listener<T> listener, ErrorListener errorListener) {
    super(Method.GET, url, errorListener);
    this.clazz = clazz;
    this.headers = headers;
    this.listener = listener;
}

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
    return headers != null ? headers : super.getHeaders();
}

@Override
protected void deliverResponse(T response) {
    listener.onResponse(response);
}

@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
    try {
        String json = new String(
                response.data,
                HttpHeaderParser.parseCharset(response.headers));
        return Response.success(
                gson.fromJson(json, clazz),
                HttpHeaderParser.parseCacheHeaders(response));
    } catch (UnsupportedEncodingException e) {
        return Response.error(new ParseError(e));
    } catch (JsonSyntaxException e) {
        return Response.error(new ParseError(e));
    }
}
} 
_

クラスファイル(アクティビティ)で、次のようにthisクラスを呼び出します。

_RequestQueue queue = MyVolley.getRequestQueue();
GsonRequest<MyClass> myReq = new GsonRequest<MyClass>(Method.GET,
                                                    "http://JSONURL/",
                                                    TagList.class,
                                                    createMyReqSuccessListener(),
                                                    createMyReqErrorListener());

            queue.add(myReq);
_

また、2つのメソッドを作成する必要があります-

  1. createMyReqSuccessListener()-GsonRequestから応答を受け取ります
  2. createMyReqErrorListener()-エラーを処理する

次のように:

_private Response.Listener<MyClass> createMyReqSuccessListener() {
    return new Response.Listener<MyClass>() {
        @Override
        public void onResponse(MyClass response) {
           // Do whatever you want to do with response;
           // Like response.tags.getListing_count(); etc. etc.
        }
    };
}
_

そして

_private Response.ErrorListener createMyReqErrorListener() {
    return new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            // Do whatever you want to do with error.getMessage();
        }
    };
}
_

それが意味をなすことを願っています。

26
MSN

ここにいくつかの便利なコードスニペットがあります。

GET請願のGsonRequest:

import com.Android.volley.NetworkResponse;
import com.Android.volley.ParseError;
import com.Android.volley.Request;
import com.Android.volley.Response;
import com.Android.volley.toolbox.HttpHeaderParser;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

import Java.io.UnsupportedEncodingException;
import Java.lang.reflect.Type;

/**
 * Convert a JsonElement into a list of objects or an object with Google Gson.
 *
 * The JsonElement is the response object for a {@link com.Android.volley.Request.Method} GET call.
 *
 * @author https://plus.google.com/+PabloCostaTirado/about
 */
public class GsonGetRequest<T> extends Request<T>
{
    private final Gson gson;
    private final Type type;
    private final Response.Listener<T> listener;

    /**
     * Make a GET request and return a parsed object from JSON.
     *
     * @param url URL of the request to make
     * @param type is the type of the object to be returned
     * @param listener is the listener for the right answer
     * @param errorListener  is the listener for the wrong answer
     */
    public GsonGetRequest
    (String url, Type type, Gson gson,
     Response.Listener<T> listener, Response.ErrorListener errorListener)
    {
        super(Method.GET, url, errorListener);

        this.gson = gson;
        this.type = type;
        this.listener = listener;
    }

    @Override
    protected void deliverResponse(T response)
    {
        listener.onResponse(response);
    }

    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response)
    {
        try
        {
            String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));

            return (Response<T>) Response.success
                    (
                            gson.fromJson(json, type),
                            HttpHeaderParser.parseCacheHeaders(response)
                    );
        }
        catch (UnsupportedEncodingException e)
        {
            return Response.error(new ParseError(e));
        }
        catch (JsonSyntaxException e)
        {
            return Response.error(new ParseError(e));
        }
    }
}

POST請願のGsonRequest:

    import com.Android.volley.NetworkResponse;
    import com.Android.volley.ParseError;
    import com.Android.volley.Response;
    import com.Android.volley.toolbox.HttpHeaderParser;
    import com.Android.volley.toolbox.JsonRequest;
    import com.google.gson.Gson;
    import com.google.gson.JsonSyntaxException;

    import Java.io.UnsupportedEncodingException;
    import Java.lang.reflect.Type;

    /**
     * Convert a JsonElement into a list of objects or an object with Google Gson.
     *
     * The JsonElement is the response object for a {@link com.Android.volley.Request.Method} POST call.
     *
     * @author https://plus.google.com/+PabloCostaTirado/about
     */
    public class GsonPostRequest<T> extends JsonRequest<T>
    {
        private final Gson gson;
        private final Type type;
        private final Response.Listener<T> listener;

        /**
         * Make a GET request and return a parsed object from JSON.
         *
         * @param url URL of the request to make
         * @param type is the type of the object to be returned
         * @param listener is the listener for the right answer
         * @param errorListener  is the listener for the wrong answer
         */
        public GsonPostRequest
        (String url, String body, Type type, Gson gson,
         Response.Listener<T> listener, Response.ErrorListener errorListener)
        {
            super(Method.POST, url, body, listener, errorListener);

            this.gson = gson;
            this.type = type;
            this.listener = listener;
        }

        @Override
        protected void deliverResponse(T response)
        {
            listener.onResponse(response);
        }

        @Override
        protected Response<T> parseNetworkResponse(NetworkResponse response)
        {
            try
            {
                String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));

                return (Response<T>) Response.success
                        (
                                gson.fromJson(json, type),
                                HttpHeaderParser.parseCacheHeaders(response)
                        );
            }
            catch (UnsupportedEncodingException e)
            {
                return Response.error(new ParseError(e));
            }
            catch (JsonSyntaxException e)
            {
                return Response.error(new ParseError(e));
            }
        }
    }

これは、JSONオブジェクトに使用する方法です。

    /**
         * Returns a dummy object
         *
         * @param listener is the listener for the correct answer
         * @param errorListener is the listener for the error response
         *
         * @return @return {@link com.sottocorp.sotti.okhttpvolleygsonsample.api.GsonGetRequest}
         */
        public static GsonGetRequest<DummyObject> getDummyObject
        (
                Response.Listener<DummyObject> listener,
                Response.ErrorListener errorListener
        )
        {
            final String url = "http://www.mocky.io/v2/55973508b0e9e4a71a02f05f";

            final Gson gson = new GsonBuilder()
                    .registerTypeAdapter(DummyObject.class, new DummyObjectDeserializer())
                    .create();

            return new GsonGetRequest<>
                    (
                            url,
                            new TypeToken<DummyObject>() {}.getType(),
                            gson,
                            listener,
                            errorListener
                    );
        }

これは、JSON配列に使用する方法です。

/**
     * Returns a dummy object's array
     *
     * @param listener is the listener for the correct answer
     * @param errorListener is the listener for the error response
     *
     * @return {@link com.sottocorp.sotti.okhttpvolleygsonsample.api.GsonGetRequest}
     */
    public static GsonGetRequest<ArrayList<DummyObject>> getDummyObjectArray
    (
            Response.Listener<ArrayList<DummyObject>> listener,
            Response.ErrorListener errorListener
    )
    {
        final String url = "http://www.mocky.io/v2/5597d86a6344715505576725";

        final Gson gson = new GsonBuilder()
                .registerTypeAdapter(DummyObject.class, new DummyObjectDeserializer())
                .create();

        return new GsonGetRequest<>
                (
                        url,
                        new TypeToken<ArrayList<DummyObject>>() {}.getType(),
                        gson,
                        listener,
                        errorListener
                );
    }

これは、POST呼び出しに使用する方法です。

/**
     * An example call (not used in this example app) to demonstrate how to do a Volley POST call
     * and parse the response with Gson.
     *
     * @param listener is the listener for the success response
     * @param errorListener is the listener for the error response
     *
     * @return {@link com.sottocorp.sotti.okhttpvolleygsonsample.api.GsonPostRequest}
     */
    public static GsonPostRequest getDummyObjectArrayWithPost
            (
                    Response.Listener<DummyObject> listener,
                    Response.ErrorListener errorListener
            )
    {
        final String url = "http://PostApiEndpoint";
        final Gson gson = new GsonBuilder()
                .registerTypeAdapter(DummyObject.class, new DummyObjectDeserializer())
                .create();

        final JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("name", "Ficus");
        jsonObject.addProperty("surname", "Kirkpatrick");

        final JsonArray squareGuys = new JsonArray();
        final JsonObject dev1 = new JsonObject();
        final JsonObject dev2 = new JsonObject();
        dev1.addProperty("name", "Jake Wharton");
        dev2.addProperty("name", "Jesse Wilson");
        squareGuys.add(dev1);
        squareGuys.add(dev2);

        jsonObject.add("squareGuys", squareGuys);

        return new GsonPostRequest<>
                (
                        url,
                        jsonObject.toString(),
                        new TypeToken<DummyObject>()
                        {
                        }.getType(),
                        gson,
                        listener,
                        errorListener
                );
    }
}

すべてのコードはここから取得されます 、そして ここにOkHttp、Volley、Gsonの使用方法に関するブログ投稿があります。

8
Sotti

Gsonではなく、Jacksonライブラリに基づくカスタムjsonリクエストを作成しました。

私が指摘したいことの1つ(理解するのに何時間もかかった...):POST Jsonパラメータもサポートする場合は、RequestではなくJsonRequestから拡張する必要があります。それ以外の場合、Jsonリクエストの本文はURLエンコードされ、サーバー側ではJavaオブジェクトに変換できません。

Jacksonに基づいており、Jsonパラメータとヘッダーをサポートする私のjsonリクエストクラスを次に示します。

    public class JacksonRequest<ResponseType> extends JsonRequest<ResponseType> {

    private final ObjectMapper objectMapper = new ObjectMapper();
    private final Class<ResponseType> responseClass;
    private final Map<String, String> headers;

    private String requestBody = null;
    private static final String PROTOCOL_CHARSET = "utf-8";

    /**
     * POST method without header
     */
    public JacksonRequest(String url,
                          Object parameterObject,
                          Class<ResponseType> responseClass,
                          Response.Listener<ResponseType> listener,
                          Response.ErrorListener errorListener) {

        this(Method.POST, url, null, parameterObject, responseClass, listener, errorListener);
    }

    /**
     * @param method see also com.Android.volley.Request.Method
     */
    public JacksonRequest(int method,
                          String url,
                          Map<String, String> headers,
                          Object parameterObject,
                          Class<ResponseType> responseClass,
                          Response.Listener<ResponseType> listener,
                          Response.ErrorListener errorListener) {

        super(method, url, null, listener, errorListener);

        if (parameterObject != null)
            try {
                this.requestBody = objectMapper.writeValueAsString(parameterObject);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }

        this.headers = headers;
        this.responseClass = responseClass;
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        return headers != null ? headers : super.getHeaders();
    }

    @Override
    protected Response<ResponseType> parseNetworkResponse(NetworkResponse response) {
        try {
            String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
            ResponseType result = objectMapper.readValue(json, responseClass);
            return Response.success(result, HttpHeaderParser.parseCacheHeaders(response));

        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JsonMappingException e) {
            return Response.error(new ParseError(e));
        } catch (JsonParseException e) {
            return Response.error(new ParseError(e));
        } catch (IOException e) {
            return Response.error(new ParseError(e));
        }
    }

    /**
     * Cannot call objectMapper.writeValueAsString() before super constructor, so override the same getBody() here.
     */
    @Override
    public byte[] getBody() {
        try {
            return requestBody == null ? null : requestBody.getBytes(PROTOCOL_CHARSET);
        } catch (UnsupportedEncodingException uee) {
            VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
                    requestBody, PROTOCOL_CHARSET);
            return null;
        }
    }

}
2
cn123h