2015-09-27 167 views
0

以前也有類似的問題。但他們都沒有爲我工作。 我正在嘗試返回訂戶正在監聽的可觀察項。 每次用戶調用onError()方法時,都會調用「java.lang.IllegalStateException:預期的BEGIN_ARRAY,但BEGIN_OBJECT在第1行第2列路徑$」此錯誤。Retrofit Android:java.lang.IllegalStateException:期望BEGIN_ARRAY,但是BEGIN_OBJECT在第1行第2列路徑

這裏是我的代碼:

public Observable<List<String>> getPlaces() { 
    Retrofit retrofit = new Retrofit.Builder() 
     .addConverterFactory(GsonConverterFactory.create()) 
     .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
     .baseUrl(Urls.BASE_URL) 
     .build(); 
    RetroFitInterface service = retrofit.create(RetroFitInterface.class); 
    return service.getPlaces(); 
} 




public interface RetroFitInterface { 

    @Headers({ 
      "Accept: application/json", 
      "Content-Type: application/json" 
    }) 
    @GET(Urls.GET_POPULAR_LOCATIONS_URL) 
    Observable<List<String>> getPlaces(); 
} 

這裏是一個JSON響應:

{ 
    "locations": [ 
     "location1", 
     "location2", 
     "location3", 
     "location4", 
     "location5", 
     "location6", 
     "location7", 
    ], 
    "success": true 
} 

這是我如何訂閱用戶。

getPlaces().subscribeOn(Schedulers.io()) 
       .subscribe(new Observer<List<String>>() { 
        @Override 
        public void onCompleted() { 
         Log.d(TAG, "Search result onCompleted()!"); 
        } 

        @Override 
        public void onError(Throwable e) { 
         Log.d(TAG, "Search result onError()! " + e.toString()); 
        } 

       @Override 
       public void onNext(final List<String> result) { 
        Log.d(TAG, "This is never called."); 
       } 
      }) 
+0

列表但是,響應是內容json數組的json對象。我認爲你需要使用pojo模式。使用GSON來對JSON進行對象數組列表映射。如果你沒有明白我的觀點,請告訴我。 –

+0

你知道json基礎知識嗎?沒有!瞭解它,例外情況會很明顯。 – Selvin

+0

@BhavdipPathar從你的幫助會更好。 – Kaustubh

回答

1

你好,首先你需要轉換的JSON響應到POJO。爲此,我使用這個jsonschema2pojo來生成POJO類。

package com.example; 

import java.util.ArrayList; 
import java.util.List; 
import javax.annotation.Generated; 
import com.google.gson.annotations.Expose; 
import com.google.gson.annotations.SerializedName; 

public class LocationResponse { 

@SerializedName("locations") 
@Expose 
private List<String> locations = new ArrayList<String>(); 
@SerializedName("success") 
@Expose 
private Boolean success; 

/** 
* 
* @return 
* The locations 
*/ 
public List<String> getLocations() { 
return locations; 
} 

/** 
* 
* @param locations 
* The locations 
*/ 
public void setLocations(List<String> locations) { 
this.locations = locations; 
} 

/** 
* 
* @return 
* The success 
*/ 
public Boolean getSuccess() { 
return success; 
} 

/** 
* 
* @param success 
* The success 
*/ 
public void setSuccess(Boolean success) { 
this.success = success; 
} 

} 

把這個類放在適當的包中。在下一步我有更新RetroFitInterface接口見一擊:

public interface RetroFitInterface { 

    @Headers({ 
      "Accept: application/json", 
      "Content-Type: application/json" 
    }) 
    @GET(Urls.GET_POPULAR_LOCATIONS_URL) 
    Observable<LocationResponse> getPlaces(); 
} 

最後,這是你應該如何訂閱用戶。

getPlaces().subscribeOn(Schedulers.io()) 
       .subscribe(new Observer<LocationResponse>() { 
        @Override 
        public void onCompleted() { 
        } 

        @Override 
        public void onError(Throwable e) { 
        } 

       @Override 
       public void onNext(final LocationResponse result) { 
        // your result is here 
        if(result.getSuccess()){ 
          //result.getLocations(); 
        } 
       } 
      }) 

讓我知道你是否需要任何幫助。

+0

如果您不想使用Jackson註釋,則可以將其刪除。 –

+0

你能喲瞭解這個 –

+0

這工作。雖然不需要公開。謝謝。 – Kaustubh

3

當前您嘗試將json反序列化爲List<String>類型。但是List<>在json中是這樣表示的:[object1, object2, object3]。另一方面,您的json實際上是一個對象,其中包含的列表。

{ 
    "locations": [ 
     "location1", 
     "location2", 
     "location3", 
     "location4", 
     "location5", 
     "location6", 
     "location7", 
    ], 
    "success": true 
} 

的POJO(Java類),這將等同於上述JSON看起來是這樣的:

public class LocationsResponse { 

    List<String> locations; 
    String success; 

} 

因此,要回答你的問題,你需要創建LocationsResponse類,並使用爲您響應類型:

public interface RetroFitInterface { 

    @Headers({ 
      "Accept: application/json", 
      "Content-Type: application/json" 
    }) 
    @GET(Urls.GET_POPULAR_LOCATIONS_URL) 
    Observable<LocationsResponse> getPlaces(); 
} 
+0

我不得不添加@SerializedName(「locations」)才能使其工作。 – Kaustubh

+0

如果java字段與json中的名稱相同,則afaik gson不需要'@ SerializedName',但可以使用 – wasyl

相關問題