making a GSON request using volley
Asked Answered
S

3

14

I have the following json response

{
  "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"
        }
      ]
    }
  ]
}

I have created the following classes for GSON request. How do I make the GSON request and store the values for the response using a volley request. What should the GSON request be like?

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;
    }
}
Script answered 2/7, 2014 at 17:55 Comment(4)
You've added a lot of code, but it's not actually anything about what you've tried... post the code, where you're trying to create the Volley request. If I'm not mistaken, GSON should be able to convert an object directly to a JSON object, just by calling gson.toJson(myObject). Also check out this tutorial: mkyong.com/java/… for parsing objects to and from Json.Cnossus
I have tried creating the GSON request class using the standardized class [link]github.com/Nemisis/OkVolley/blob/master/src/com/asa/okvolley/…). now how do i call this class in my activity?Script
Is there a good tutorial for android with a complex JSON requestScript
Take a look at this answer -> https://mcmap.net/q/827197/-how-to-parse-android-volley-gson-request-to-a-list-collection-of-objectsAdumbrate
D
33

Just create a GsonRequest Class as follows (taken from 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));
    }
}
} 

Now in your class file (Activity) just call the this class as follows:

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

            queue.add(myReq);

We also need to create two methods -

  1. createMyReqSuccessListener() - receive the response from GsonRequest
  2. createMyReqErrorListener() - to handle any error

as follows:

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.
        }
    };
}

and

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

I hope it will make some sense.

Dismuke answered 28/9, 2014 at 13:9 Comment(3)
How can I add JsonObject as raw data? I tried getBody() but it doesn't worked :(Ramon
GsonRequest invocation parameters type and order does not match with the definition you have provided.Slurp
What is "MyVolley" and your "TagList" class in this instance?Amoreta
A
9

Here some useful code snippets.

GsonRequest for GET petitions:

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

GsonRequest for POST petitions:

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

This is how you use it for JSON objects:

    /**
         * 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
                    );
        }

This is how you use it for JSON arrays:

/**
     * 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
                );
    }

This is how you use it for POST calls:

/**
     * 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
                );
    }
}

All the code is taken from here, and you have a blog post about how to use OkHttp, Volley and Gson here.

Adumbrate answered 13/7, 2015 at 14:42 Comment(0)
A
2

I just made a custom json request which is based on Jackson library instead of Gson.

One thing I want to point out (it took my many hours to figure out...): if you want to support POST Json parameter as well, you should extend from JsonRequest instead of Request. Otherwise your Json request body will be url-encoded, on the server side you cannot convert it back to java object.

Here is my json request class, which is based on Jackson and supports Json parameter and header:

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

}
Astute answered 23/12, 2014 at 21:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.