2014-10-28 103 views
3

我想使用android volley進行Gson請求。目前它工作正常,我很高興。但是,爲什麼我嘗試獲取列表<>或我的代碼集合不再有效。如何解析android volley gson請求到列表/對象集合

當前代碼:

public class ReviewModel 
{ 
    public long Id; 
    public Strring Description; 
} 

這裏是我如何用我的GSON類:

GsonRequest<ReviewModel> jsObjRequest = new GsonRequest<ReviewModel>(Request.Method.GET, 
      url, ReviewModel.class, new Response.Listener<ReviewModel>() { 
       @Override 
       public void onResponse(ReviewModel response) { 
        ReviewsHandleOkResponse(response); 
       } 

      }, new ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError error) { 
        ReviewsHandleErrorResponse(error); 
       } 
      }); 
    Network.getInstance(getActivity()).addToRequestQueue(jsObjRequest); 
} 

這裏是我的排球GSON請求類:

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 Map<String, String> params; 
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(int method, String url, Class<T> clazz, 
     Map<String, String> headers, Map<String, String> params, 
     Listener<T> listener, ErrorListener errorListener) { 
    super(method, Network.getFullUrl(url), errorListener); 
    this.clazz = clazz; 
    this.headers = headers; 
    this.params = params; 
    this.listener = listener; 
} 

/** 
* Recieves header 
* 
* @param method 
* @param url 
* @param clazz 
* @param params 
* @param listener 
* @param errorListener 
*/ 
public GsonRequest(int method, String url, Class<T> clazz, 
     Map<String, String> params, Listener<T> listener, 
     ErrorListener errorListener) { 
    super(method, Network.getFullUrl(url), errorListener); 
    this.clazz = clazz; 
    this.headers = new HashMap<String, String>(); 
    this.params = params; 
    this.listener = listener; 
} 

/** 
* No params or headers 
* 
* @param method 
* @param url 
* @param clazz 
* @param listener 
* @param errorListener 
*/ 
public GsonRequest(int method, String url, Class<T> clazz, 
     Listener<T> listener, ErrorListener errorListener) { 
    super(method, Network.getFullUrl(url), errorListener); 
    this.clazz = clazz; 
    this.headers = new HashMap<String, String>(); 
    this.params = new HashMap<String, String>(); 
    this.listener = listener; 
} 

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

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

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

但是當我Rey和解析它到一個List<ReviewModel>我得到編譯錯誤。

從我的研究,我需要做一些事情,如:

Type collectionType = new TypeToken<ArrayList<ReviewModel>>(){}.getType();  
    // api/v1/reviews/products/{productId}/{pageNumber}/{pageSize} 
    String url = "api/v1/reviews/products/" + productId + "/" + currentPage + "/" + pageSize; 
    GsonRequest<ArrayList<ReviewModel>> jsObjRequest = new GsonRequest<ArrayList<ReviewModel>>(Request.Method.GET, 
      url, (Class<ArrayList<ReviewModel>>) collectionType, new Response.Listener<ArrayList<ReviewModel>>() { 
       @Override 
       public void onResponse(ArrayList<ReviewModel> response) { 
        ReviewsHandleOkResponse(response); 
       } 

      }, new ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError error) { 
        ReviewsHandleErrorResponse(error); 
       } 
      }); 
    Network.getInstance(getActivity()).addToRequestQueue(jsObjRequest); 
} 

,但是這給了我以下錯誤:

10-28 21:12:59.940: E/AndroidRuntime(28564): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.menu/com.menu.activities.ProductViewActivity}: java.lang.ClassCastException: com.google.gson.internal.$Gson$Types$ParameterizedTypeImpl cannot be cast to java.lang.Class

我是否需要修改我的GsonRequest類,和添加另一個不帶類型類的構造函數?

+0

看看GSON的TypeToken後。 – njzk2 2014-10-28 19:16:37

+0

我已經在我的文章中提到過,但是我無法弄清楚它是如何適合我的GsonRequest類的。 – Zapnologica 2014-10-28 19:27:28

+0

'(Class >)collectionType'不轉換。 'Type'不是'Class'。修改你的'GsonRequest'來接受'Type'。 – njzk2 2014-10-28 19:29:29

回答

2

使用YourClass[]獲取排球請求中的對象列表。它解決了我的問題。以下代碼應該對您有所幫助:

GsonRequest<ReviewModel[]> jsObjRequest = new GsonRequest<ReviewModel[]>(Request.Method.GET, 
     url, ReviewModel[].class, new Response.Listener<ReviewModel[]>() { 
      @Override 
      public void onResponse(ReviewModel[] response) { 
       ReviewsHandleOkResponse(response); 
      } 
     }, new ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 
       ReviewsHandleErrorResponse(error); 
      } 
     }); 
Network.getInstance(getActivity()).addToRequestQueue(jsObjRequest); 
} 
+0

我們也可以通過創建一個新的bean來實現這種行爲,讓我們說ParentModel,它將ReviewModel的列表作爲變量,只是getter和setter爲相同的。因此,您可以直接用上面的seudo代碼中的ParentModel替換ReviewModel [] – 2017-03-09 08:29:39

0

我最近需要自己實施一個解決方案,以便您可以繼續使用。 自定義GsonArrayRequest。

public class GsonArrayRequest<T> extends Request<ArrayList<T>> { 
    private final Gson gson = new Gson(); 
    private final Class<T> clazz; 
    private final Map<String, String> headers; 
    private final Response.Listener<ArrayList<T>> listener; 

    /** 
    * Make a GET request and return a parsed object from JSON. 
    * @param clazz Relevant class object, for Gson's reflection 
    * @param url  URL of the request to make 
    * @param headers Map of request headers 
    */ 
    public GsonArrayRequest(String url, Class<T> clazz, Map<String, String> headers, 
         Response.Listener<ArrayList<T>> listener, Response.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 Response<ArrayList<T>> parseNetworkResponse(NetworkResponse response) { 
    try { 
     String json = new String(
       response.data, 
       HttpHeaderParser.parseCharset(response.headers)); 

     Type listType = com.google.gson.internal.$Gson$Types.newParameterizedTypeWithOwner(null, ArrayList.class, clazz); 
     ArrayList<T> tList = gson.fromJson(json, listType); 
     return Response.success(
       tList, 
       HttpHeaderParser.parseCacheHeaders(response)); 
    } catch (UnsupportedEncodingException e) { 
     return Response.error(new ParseError(e)); 
    } catch (JsonSyntaxException e) { 
     return Response.error(new ParseError(e)); 
    } 
} 

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

您可以使用它像這樣:

GsonArrayRequest<StoreWorkout> gsonArrayRequest = new GsonArrayRequest<>(
     url, AngryPugs.class, null, new Response.Listener<ArrayList<AngryPugs>>() { 
    @Override 
    public void onResponse(ArrayList<AngryPugs> response) { 
     // your list here 
    } 
}, new Response.ErrorListener() { 
    @Override 
    public void onErrorResponse(VolleyError error) { 

    } 
}); 

添加請求

VolleySingleton.getInstance(this).addToRequestQueue(gsonArrayRequest);