다음과 같이 "_embedded"태그로 JSON을 래핑했습니다.
{
"_embedded" : {
"events" : [ { ... }]}
인터페이스와 함께 개조를 사용하고 있습니다.
public interface IEventRest {
@GET("/events/search/findByPlaceId")
Observable<List<Event>> getEventList(@Query("placeId")String placeId);
}
그리고 이것은 내 REST 클래스입니다.
public class EventRest implements IEventRest {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Event[].class, new MyDeserializer())
.create();
private Retrofit getRetrofitClient() {
final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
final OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
return new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.baseUrl(UrlUtils.URL)
.client(client)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
@Override
public Observable<List<Event>> getEventList(String placeId) {
final IEventRest placeRest = getRetrofitClient().create(IEventRest.class);
return placeRest.getEventList(placeId)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread());
}
private class MyDeserializer implements JsonDeserializer<List<Event>> {
@Override
public List<Event> deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException {
JsonElement content = je.getAsJsonObject().get("_embedded");
Type collectionType = new TypeToken<Collection<Event>>(){}.getType();
return new Gson().fromJson(content, collectionType);
}
}
}
그러나 placeRest.getEventList (placeId)를 호출하면 예외가 발생합니다.
java.lang.IllegalStateException: Exception thrown on Scheduler.Worker thread. Add `onError` handling.
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:57)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: rx.exceptions.OnErrorNotImplementedException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:386)
at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:383)
at rx.internal.util.ActionSubscriber.onError(ActionSubscriber.java:44)
at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:152)
at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:115)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.checkTerminated(OperatorObserveOn.java:276)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:219)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:351)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:80)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:117)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$RequestArbiter.request(RxJavaCallAdapterFactory.java:171)
at rx.internal.operators.OperatorSubscribeOn$1$1$1.request(OperatorSubscribeOn.java:80)
at rx.Subscriber.setProducer(Subscriber.java:211)
at rx.internal.operators.OperatorSubscribeOn$1$1.setProducer(OperatorSubscribeOn.java:76)
at rx.Subscriber.setProducer(Subscriber.java:205)
at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:152)
at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:138)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:9860)
at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)
at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:221)
무엇이 잘못되었는지 알아 내도록 도와 주시겠습니까? 미리 감사드립니다.
"_embedded"태그로 래핑 된 JSON이 있습니다.
그리고 그것이 바로 문제입니다. Gson은 데이터가 래핑 된 것을 알지 못합니다. 보이는 문자열에서 객체라는 것만 신경을 씁니다.
여기 에서 미리보기를 가져옵니다. 총 3 개의 개체가 표시됩니다.
Event.java
(JSON이 어떻게 생겼는지 생략했기 때문에 생성되지 않았습니다)
Embedded.java
import java.util.ArrayList;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Embedded {
@SerializedName("events")
@Expose
private List<Event> events = new ArrayList<Event>();
public Embedded() {
}
public Embedded(List<Event> events) {
this.events = events;
}
public List<Event> getEvents() {
return events;
}
public void setEvents(List<Event> events) {
this.events = events;
}
}
Response.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Response {
@SerializedName("_embedded")
@Expose
private Embedded embedded;
public Response() {
}
public Response(Embedded embedded) {
this.embedded = embedded;
}
public Embedded getEmbedded() {
return embedded;
}
public void setEmbedded(Embedded embedded) {
this.embedded = embedded;
}
}
그리고, 이제, 약 개조 염려는 Call<Response>
, 어떤 당신은 전화 후 수.getEmbedded().getEvents()
또는 MyDeserializer
기존 코드의 문제인 것 같기 때문에 더 많은 작업을 할 수 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다