2015-09-27 163 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

相关问题