making a GSON request using volley

后端 未结 3 458
既然无缘
既然无缘 2020-12-12 21:37

I have the following json response

{
  \"tag\": [
    {
      \"listing_count\": 5,
      \"listings\": [
        {
          \"source\": \"source1\",
               


        
相关标签:
3条回答
  • 2020-12-12 21:58

    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;
            }
        }
    
    }
    
    0 讨论(0)
  • 2020-12-12 21:59

    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.

    0 讨论(0)
  • 2020-12-12 22:01

    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.

    0 讨论(0)
提交回复
热议问题