2014-07-02 9 views
10

Mam następujące odpowiedzi jsonskładając wniosek GSON korzystając z woleja

{ 
    "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 zostały utworzone następujące klasy na życzenie GSON. Jak utworzyć żądanie GSON i zapisać wartości dla odpowiedzi za pomocą żądania volley. Jak powinno wyglądać żądanie 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; 
    } 
} 
+0

dodanych dużo kodu, ale nie jest to rzeczywiście coś o tym, co” próbowałem ... opublikować kod, w którym próbujesz utworzyć żądanie "Volley". Jeśli się nie mylę, GSON powinien móc przekonwertować obiekt bezpośrednio na obiekt 'JSON', po prostu wywołując' gson.toJson (myObject) '. Zapoznaj się także z tym samouczkiem: http://www.mkyong.com/java/how-do-convert-java-object-to-from-json-format-gson-api/ do parsowania obiektów do iz Json. – Darwind

+0

Próbowałem utworzyć klasę żądania GSON przy użyciu standardowej klasy [link] https://github.com/Nemisis/OkVolley/blob/master/src/com/asa/okvolley/GsonRequest.java). jak mogę nazwać tę klasę w mojej działalności? –

+0

Czy istnieje dobry samouczek dla Androida z złożonym żądaniem JSON –

Odpowiedz

22

Wystarczy utworzyć GsonRequest klasa (zaczerpnięte z 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)); 
    } 
} 
} 

Teraz w pliku klasy (aktywność) po prostu zadzwonić do tej klasy następująco następująco:

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

      queue.add(myReq); 

Mamy również trzeba utworzyć dwie metody -

  1. createMyReqSuccessListener() - otrzyma odpowiedzi od GsonRequest
  2. createMyReqErrorListener() - obsługiwać jakikolwiek błąd

następująco:

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

i

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

Mam nadzieję, że będzie to jakiś sens.

+1

Jak mogę dodać JsonObject jako surowe dane? Próbowałem getBody(), ale to nie zadziałało :( – Krishnakant

+1

co z post? –

+0

'Parametr i parametry parametru wywołania GsonRequest nie są zgodne z podaną definicją. – zionpi

2

Właśnie utworzyłem niestandardowe żądanie json, które jest oparte na bibliotece Jacksona zamiast Gson.

Jedna rzecz, którą chcę wskazać (zajęło mi to wiele godzin, aby dowiedzieć się ...): jeśli chcesz również wspierać parametr POST Json, powinieneś rozszerzyć z JsonRequest zamiast Request. W przeciwnym razie treść żądania Json będzie kodowana przez URL, po stronie serwera nie będzie można przekonwertować go z powrotem do obiektu java.

Oto moja prośba json klasy, która opiera się na Jacksona i obsługuje parametr JSON i nagłówek:

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

} 
7

Oto kilka przydatnych fragmentów kodu.

GsonRequest dla petycji otrzymujemy:

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 dla petycji postu:

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

ten sposób można go używać dla obiektów 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 
        ); 
     } 

W ten sposób można używać dla macierzy 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 
       ); 
    } 

ten sposób można go używać do POST wzywa:

/** 
    * 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 i masz blog post about how to use OkHttp, Volley and Gson here.