2017-08-31 74 views
1

我在獲取JSON字符串並在Android應用程序中使用它時面臨一些困難。所以,我有這個類產品組別,在那裏我已經定義的所有領域的類別必須具備:Android - 使用Retrofit不帶數組標題的JSON解析

public class Category2 { 

    @SerializedName("_id") 
    private String _id; 
    @SerializedName("name") 
    private String name; 
    @SerializedName("tasks") 
    private int tasks; 

    public Category2(String _id, String name, int tasks) { 

     this._id = _id; 
     this.name = name; 
     this.tasks = tasks; 
    } 


    public String get_id(){ 
     return _id; 
    } 
    public void set_id(String _id){ 
     this._id = _id; 
    } 
    public String getName(){ 
     return name; 
    } 
    public void setName(String name){ 
     this.name = name; 
    } 
    public int getTasks() { 
     return tasks; 
    } 
    public void setTasks(int tasks){ 
     this.tasks = tasks; 
    } 
} 

而且我有一類叫做CategoryResponse,基本上是,我從改造要求獲得產品組別的列表:

public class CategoryResponse { 

    private List<Category2> results; 

    public List<Category2> getResults() { 
     return results; 
    } 

    public void setResults(List<Category2> results) { 
     this.results = results; 
    } 
} 

一般來說,我處理有一個名稱爲結果,即使它像一個項目列表JSON字符串:

{"genres":[{"id":28,"name":"Action"},{"id":12,"name":"Adventure"}]} 

當JSON字符串是像上面我只需要添加一個序列化的列表結果列表的聲明之上:

@SerializedName("genres") 

當我宣佈我的GET方法,它工作得很好:

@GET("/v3/projects/{projectId}/categories/") 
    Call<CategoryResponse> getProjectCategories(@Query("projectId") String projectId, @Header("Token") String token); 

而且我把它在我的活動:

categoryService = 
     CategoryClient.getClient().create(CategoryService.class); 

Call<CategoryResponse> call = categoryService.getProjectCategories(projectId,token); 
call.enqueue(new Callback<CategoryResponse>() { 
    @Override 
    public void onResponse(Call<CategoryResponse> call, Response<CategoryResponse> response) { 

     //int statusCode = response.code(); 
     listCategories = new ArrayList<>(); 
     listCategories = response.body().getResults(); 
     System.out.println("Size: " + response.body().getResults().size()); 
    } 

    @Override 
    public void onFailure(Call<CategoryResponse> call, Throwable t) { 
     // Log error here since request failed 
     Log.e(TAG, t.toString()); 
    } 
}); 

但我現在有一個類別是這樣的:

[ 
    { 
     "_id": "59a6b18b2ba5c14bb76f28c8", 
     "createdAt": "2017-08-30T12:37:31.885Z", 
     "updatedAt": "2017-08-30T12:37:31.885Z", 
     "projectId": "598cbc74a1d0e57722ca98d1", 
     "companyId": "5602eb7ce49c9cd70409f206", 
     "name": "Arquitetura", 
     "__v": 0, 
     "tasks": 0 
    }, 
    { 
     "_id": "59a6b1be2ba5c14bb76f28c9", 
     "createdAt": "2017-08-30T12:38:22.407Z", 
     "updatedAt": "2017-08-30T12:38:22.407Z", 
     "projectId": "598cbc74a1d0e57722ca98d1", 
     "companyId": "5602eb7ce49c9cd70409f206", 
     "name": "Manutenção", 
     "__v": 0, 
     "tasks": 0 
    } 
] 

所以我不能序列化結果列表的名稱,當我調用「response.body.GetResults()」時,我得到空值。

+0

嘗試刪除'Category2'拷貝構造函數。如果存在可用的複製構造函數,則在創建新的'Category2'類對象時不會調用默認的Constructror。試試這個,告訴我它是否可以工作 –

回答

2

您的服務代碼只是返回一個Call<ArrayList<Category2>>

@GET("/v3/projects/{projectId}/categories/") 
Call<ArrayList<Category2>> getProjectCategories(@Path("projectId") String projectId, @Header("Token") String token); 

解析將正確地改造做出這種方式。

編輯

你如何調用這個服務:

categoryService = 
     CategoryClient.getClient().create(CategoryService.class); 

Call<ArrayList<Category2>> call = categoryService.getProjectCategories(projectId,token); 
call.enqueue(new Callback<ArrayList<Category2>>() { 
    @Override 
    public void onResponse(Call<ArrayList<Category2>> call, Response<ArrayList<Category2>> response) { 
     listCategories = response.body(); 
     System.out.println("Size: " + listCategories.size().toString()); 
    } 

    @Override 
    public void onFailure(Call<ArrayList<Category2>> call, Throwable t) { 
     // Log error here since request failed 
     Log.e(TAG, t.toString()); 
    } 
}); 
+0

感謝您的回覆!我試圖做你提出的改變,但我仍然得到:試圖調用空對象引用的虛擬方法'int java.util.ArrayList.size()'。我知道結果不應該返回爲null,因爲我傳遞了令牌和項目ID。 –

+0

可能是因爲改造服務?當您想要將參數添加到調用路徑時,您應該使用'@Path(「projectId」)'註釋而不是'@Query(「projectId」)''。 –

+0

我更改爲「@Path」,但我收到相同的錯誤。我正在測試使用郵差的鏈接,它工作正常,檢索它應該的結果。但在Postman中,當我添加標題時,我添加了「Authorization」的Key和值,這是標記。在應用程序中,我不添加密鑰。你認爲是因爲這個原因嗎? –

0

添加新字段到類產品組別與指示它們是短暫的,即,它們不會被序列化。 Gson: How to exclude specific fields from Serialization without annotations

public class Category2 { 

@SerializedName("_id") 
private String _id; 
@SerializedName("name") 
private String name; 
@SerializedName("tasks") 
private int tasks; 

private transient String createdAt, updatedAt, projectId, companyId; 
private transient int __v; 

public Category2(String _id, String name, int tasks) { 

    this._id = _id; 
    this.name = name; 
    this.tasks = tasks; 
} 


public String get_id(){ 
    return _id; 
} 
public void set_id(String _id){ 
    this._id = _id; 
} 
public String getName(){ 
    return name; 
} 
public void setName(String name){ 
    this.name = name; 
} 
public int getTasks() { 
    return tasks; 
} 
public void setTasks(int tasks){ 
    this.tasks = tasks; 
} 
} 

編輯

更改此

@GET("/v3/projects/{projectId}/categories/") 
Call<List<Category2>> getProjectCategories(@Path("projectId") String projectId, @Header("Authorization") String token); 

categoryService = 
    CategoryClient.getClient().create(CategoryService.class); 

Response<CategoryResponse> response = categoryService.getProjectCategories(projectId,token).execute(); 

//int statusCode = response.code(); 
listCategories = new ArrayList<>(); 
listCategories = response.body().getResults(); 
System.out.println("Size: " + response.body().getResults().size()); 
+0

感謝您的回覆!我做了你的建議,但我得到:嘗試調用虛擬方法'java.util.List com.construct.v2.models.category.CategoryResponse.getResults()'對空引用但我知道對於令牌和ProjectID我正在傳遞我不應該得到一個空響應。 –

+0

請參閱我的版本@MarcosGuimaraes – joao86