我有一个应用程序,它正在查询一个endpoint,然后简单地将响应放在ListView中。然而,“onFailure”返回消息“预期BEGIN_ARRAY但BEGIN_OBJECT第1行第2列路径$”。
我看过类似的问题,但似乎无法在我的应用程序中找到答案。
在OnCread中,我设置了endpoint的基本URL,然后添加了我的API密钥,并调用了一个接口,该接口查询必要的参数:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
myLocationButton = findViewById(R.id.myLocationBtn);
myLocationButton.setOnClickListener(this);
eventList = findViewById(R.id.evenListView);
SearchView searchView = findViewById(R.id.searchView);
searchView.setIconified(false);
searchView.clearFocus();
String API_BASE_URL = "https://app.ticketmaster.com/discovery/v2/";
final String API_KEY = "HIDDEN";
OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request original = chain.request();
HttpUrl originalHttpUrl = original.url();
HttpUrl url = originalHttpUrl.newBuilder()
.addQueryParameter("apikey", API_KEY)
.build();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder().url(url);
Request request = requestBuilder.build();
return chain.proceed(request);
}
}).build();
Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(
GsonConverterFactory.create()
);
Retrofit retrofit = builder.client(httpClient).build();
ITicketMasterAPI event = retrofit.create(ITicketMasterAPI.class);
Call<List<TicketMasterEvent>> call = event.getLocalEvents("manchester",
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null);
call.enqueue(new Callback<List<TicketMasterEvent>>() {
@Override
public void onResponse(Call<List<TicketMasterEvent>> call, Response<List<TicketMasterEvent>> response) {
List<TicketMasterEvent> events = response.body();
eventList.setAdapter(new TMEventAdapter(SearchActivity.this, events));
Toast.makeText(SearchActivity.this,"something happened", Toast.LENGTH_LONG).show();
}
@Override
public void onFailure(Call<List<TicketMasterEvent>> call, Throwable t) {
RequestBody test = call.request().body();
Toast.makeText(SearchActivity.this, "didn't work", Toast.LENGTH_LONG).show();
}
});
}
下面是查询的界面:
public interface ITicketMasterAPI {
@GET("events.json")
Call <List<TicketMasterEvent>> getLocalEvents(
@Query("city") String city,
@Query("id") String id,
@Query("keyword") String keyword,
@Query("attractionId") String attractionId,
@Query("venueId") String venueId,
@Query("postalCode") String postalCode,
@Query("latlong") String latlong,
@Query("radius") String radius,
@Query("unit") String unit,
@Query("source") String source,
@Query("locale") String locale,
@Query("marketId") String marketId,
@Query("startDateTime") String startDateTime,
@Query("endDateTime") String endDateTime,
@Query("includeTBA") String includeTBA,
@Query("includeTBD") String includeTBD,
@Query("includeTest") String includeTest,
@Query("size") String size,
@Query("page") String page,
@Query("sort") String sort,
@Query("onsaleStartDateTime") String onsaleStartDateTime,
@Query("onsaleEndDateTime") String onsaleEndDateTime,
@Query("countryCode") String countryCode,
@Query("stateCode") String stateCode,
@Query("stateCode") String classificationName,
@Query("classificationId") String classificationId,
@Query("dmaId") String dmaId,
@Query("segmentId") String segmentId,
@Query("segmentName") String segmentName,
@Query("promoterId") String promoterId,
@Query("clientVisibility") String clientVisibility,
@Query("geoPoint") String geoPoint,
@Query("includeLicensedContent") String includeLicensedContent,
@Query("includeSpellcheck") String includeSpellcheck);
}
以及数据的模型。目前我只想知道这个名字:
public class TicketMasterEvent {
public String eventName;
public String getEventName() {
return eventName;
}
更新
我没有将所有列表更改为仅键入“TicketMasterEvent”,这将导致它返回“200-OK”的状态代码。然而,正如建议的那样,我查看了邮差中的实际响应,这就是我得到的:
更新2
我做了以下改变。。。
public class TicketMasterEvent {
@SerializedName("_embedded")
EventEmbedded embedded;
public String getName() {
return name;
}
@SerializedName("name")
@Expose
private String name;
@SerializedName("type")
@Expose
private String type;
@SerializedName("id")
@Expose
private int id;
@SerializedName("test")
@Expose
private String test;
@SerializedName("url")
@Expose
private String url;
@SerializedName("locale")
@Expose
private String locale;
@SerializedName("images")
@Expose
private List<EventImages> images;
}
public class EventEmbedded {
@SerializedName("events")
@Expose
List<TicketMasterEvent> events;
}
更新3-它的工作原理!
好的,下面是我得到的回复:
这似乎只在调用类型为TicketMasterEvent而不是列表时才起作用——在界面中也是如此。然而,我注意到它的主体中有一些空属性——这是一个问题吗?
此外,由于没有将其作为列表返回,我无法让它填充我的列表视图——对此有什么想法吗?
解决方案1
因此,要将您的JSON响应映射到一个模型类,您只需使用此站点寻求帮助。只需选择源代码类型的JSON和注释样式的Gson。结果应该是这样的(伪代码):
class TicketMasterEvent {
@Expose
Embedded embedded;
}
class Embedded {
@Expose
List<Event> events;
}
还有活动课。现在,它可能会将嵌入式
作为\u embedded
吐出来,这不是真正的Java风格。要改变这一点,只需执行以下操作:
@SerializedName("_embedded")
Embedded embedded;
这个注释告诉解析器将_embedded
映射到embedded
。哦,是的,还必须创建一个模型类Image
。
解决方案2
一种更好但更复杂的方法是获取原始JSON响应
,然后迭代响应对象
,这样就可以访问JsonArray
事件,它是唯一包含响应部分的数据。这里描述了如何迭代JsonObject
。然后你只需要将JsonArray
转换到你的列表中
List<Event> events = mGson.fromJson(jsonArray.toString(), new TypeToken<List<Event>>(){}.getType());
仅供参考:您的
事件
类当然可以通过解决方案1开头链接的站点生成。要做到这一点,只需复制数组中第一个对象的内容:)。在那个事件
a类列表中
希望这能有所帮助!
问题内容: 我遇到错误了。 由于以下原因,无法解析JSON:com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期为BEGIN_ARRAY,但在第1行第2列为BEGIN_OBJECT 服务器网址 执行请求 上课后 我该如何解决? 问题答案: 您在注释中声明返回的JSON是这样的: 您告诉Gson您有一个对象数组:
在尝试将json文本文件解析为餐厅对象的数组列表时,我遇到了错误“应为BEGIN\u数组,但在第1行第2列路径处为BEGIN\u对象。”我不知道哪里弄错了,因为我的Restaurant类中的数据成员与json文件中的字段完全对应。 主要的 餐厅类 txt文件
问题内容: 我知道这不是第一次有人问这个问题,但是有了Retrofit2,我找不到适合我问题的正确解决方案。我遵循了在线教程,效果很好。当我将相同的代码应用于自己的端点时,会出现以下异常:我不知道该如何解决。 接口: 客户代码: 此代码与此有效负载一起使用: 但与此不: 我的音乐课: 问题答案: 当您说“此代码正在使用此有效负载:…而不是与此有效:: …”时,这是预期的,这就是假定的工作方式。实际
问题内容: 我知道这不是第一次有人问这个问题,但是有了Retrofit2,我找不到合适的解决方案。我遵循了在线教程,效果很好。当我将相同的代码应用于自己的端点时,会出现以下异常:我不知道该如何解决。 接口: 客户代码: 此代码与此有效负载一起使用: 但与此不: 我的音乐课: 问题答案: 当你说“此代码正在使用此有效负载:…而不是与此:: …”时,这是预期的,这就是假定的工作方式。实际上,错误消息告
问题内容: 我刚从gson开始,我想解析一个以对象开头的JSON字符串,并且总是得到相同的错误JSON。 我一直遇到错误: 我的日志中的错误指向这一行: 这是我的pojo 问题答案: 您的主类将数据作为列表。您的JSON将其作为对象。类型需要匹配。如果您希望main中只有1个数据,请不要使用列表。如果期望1个或多个数据,则使生成数据的代码向下发送一个数组(即使该数组中只有1个对象)。
在阅读@Ridcully的响应之后,我想问一下是否有一种方法可以更新,以便它知道JSON是一个数组。比如?