gpt4 book ai didi

java - 如何修复 "Expected BEGIN_OBJECT but was BEGIN_ARRAY"?

转载 作者:行者123 更新时间:2023-12-02 09:34:49 24 4
gpt4 key购买 nike

我正在使用 Retrofit 2 发送 HTTP 请求,我已经定期完成了所有操作,但是,情况“不标准”。我有一个问题,响应类中要接收的对象之一曾经作为对象发送,而另一个作为列表发送。所以我不知道是在响应类中将其初始化为对象还是数组。

Here is my full JSON response:

{
"data": [
{
"name": "John",
"surname": "Smith",
"nicname": "Joe",
"age": "32",
"description": "Example",
"state": "Nevada",
"city": "Las Vegas",
"job": "Security",
"adress": "Some adress 1",
"postcode": "412421",
"details": {
"intro": {
"title": "Mr.",
"married": "No",
"children": "2"
},
"rest": {
"pitctures":"24",
"chats": "7",
"lastChat": "12-01-2016",
"lastVisited": "07-04-2017",
}
}
},
{
"name": "John",
"surname": "Smith",
"nicname": "Joe",
"age": "32",
"description": "Example",
"state": "Nevada",
"city": "Las Vegas",
"job": "Security",
"adress": "Some adress 1",
"postcode": "412421",
"details": {
"intro": {
"title": "Mr.",
"married": "No",
"children": "No"
},
"rest": []
}
}
],
"errors": false,
"update_notifications": {
"message": [],
"friend_request": [],
"code": "IzS0hivN1cyHBdygpeWv"
}
}

Details.java class:

public class Details {

@SerializedName("intro")
@Expose
private Intro intro;
@SerializedName("rest")
@Expose
private Rest restObject;

private ArrayList<Rest> restList;

public Details(Intro intro, Rest restObject) {
this.intro = intro;
this.restObject = restObject;
}

public Details(Intro intro, ArrayList<Rest> restList) {
this.intro = intro;
this.restList = restList;
}

public Intro getIntro() {
return intro;
}

public void setIntro(Intro intro) {
this.intro = intro;
}

public Rest getRestObject() {
return restObject;
}

public void setRestObject(Rest restObject) {
this.restObject = restObject;
}

public ArrayList<Rest> getRestList() {
return restList;
}

public void setRestList(ArrayList<Rest> restList) {
this.restList = restList;
}
}

And here is my CustomDeserializer.java (rest array neeed to be empty, maybe that's a problem) based on @Farid's answer:

public class CustomDeserializer implements JsonDeserializer<Details> {

@Override
public Details deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

JsonObject detailsObject = json.getAsJsonObject().get("details").getAsJsonObject();
Details details;

JsonObject introObject = detailsObject.get("intro").getAsJsonObject();
String title = introObject.get("title").getAsString();
String married = introObject.get("married").getAsString();
String children = introObject.get("children").getAsString();

try {
JsonObject restObject = detailsObject.get("rest").getAsJsonObject();

String pitctures = restObject.get("pitctures ").getAsString();
String chats = restObject.get("chats ").getAsString();
String lastChat = restObject.get("lastChat ").getAsString();
String lastVisited = restObject.get("lastVisited ").getAsString();

details = new Details(new Intro(title, married, children),
new Rest(pitctures, chats, lastChat, lastVisited));
}catch (IllegalStateException e){
JsonArray restArray = detailsObject.get("rest").getAsJsonArray();
ArrayList<Rest> restList = new ArrayList<>();
details = new Details(new Intro(title, married, children), restList);
}
return details;
}
}

In MainActivity based on @Farid's answer:

Gson gsonConverter = new GsonBuilder().registerTypeAdapter(Details.class, new CustomDeserializer()).create();


Retrofit retrofit = new Retrofit.Builder()
.baseUrl(myUrl)
.addConverterFactory(GsonConverterFactory.create(gsonConverter))
.build();

service1 = retrofit.create(MyAPI.class);

final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
progressDialog.setMessage("Please wait!");
progressDialog.show();

final MyRequest myRequest = new MyRequest();

myRequest.setPin(pin);

final Call<MyResponse> myResponseCall = service1.get (code, myRequest);

myResponseCall.enqueue(new Callback<MyResponse>() {
@Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
}
});

最佳答案

这是可能的。您必须创建一个自定义反序列化器。如您所见,有 JsonDeserializer<Details>其类型参数为Details这意味着任何时候 GSON 尝试反序列化 Details对象,它会调用CustomDeserializer反序列化它。里面有什么Details对象应该手动反序列化,如 CustomDeserializer 中所示。类,而 Details 之外的所有其他类型类(例如 Class、String、int)将由 GSON 无缝处理

CustomDeserializer.java

    public class CustomDeserializer implements JsonDeserializer<Details> {

@Override
public Details deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

JsonObject detailsObject = json.getAsJsonObject();
Details details;
Intro intro = new Intro(detailsObject.get("intro").getAsJsonObject().get("example").getAsString());

try {
JsonObject restObject = detailsObject.get("rest").getAsJsonObject();
String example = restObject.get("example").getAsString();

details = new Details(intro, new Rest(example));
}catch (IllegalStateException e){ // In case rest is ArrayList
JsonArray restArray = detailsObject.get("rest").getAsJsonArray();
ArrayList<Rest> resList = new ArrayList<>();
for (JsonElement element: restArray){
JsonObject restObject = element.getAsJsonObject();
String example = restObject.get("example").getAsString();
resList.add(new Rest(example));
}

details = new Details(intro, resList);
}

return details;
}
}

那么你必须注册CustomDeserializerTypeAdapter如下:

 Gson gsonConverter = GsonBuilder().registerTypeAdapter(Details::class.java,
CustomDeserializer()).create();

Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gsonConverter))
///Rest of Retrofit builder code

如果您想了解有关自定义反序列化的更多信息,请搜索“gson 反序列化”并找到最吸引您的教程。

<小时/>

下面的代码 fragment 是OP特定的类

Response.java

public class Response {

private List<DataItem> data = null;
private Boolean errors;
private String example;

public List<DataItem> getData() {
return data;
}

public void setData(List<DataItem> data) {
this.data = data;
}

public Boolean getErrors() {
return errors;
}

public void setErrors(Boolean errors) {
this.errors = errors;
}

public String getExample() {
return example;
}

public void setExample(String example) {
this.example = example;
}

}

Data.java

 public class DataItem { 
private String example;
private Details details;

public String getExample() {
return example;
}

public void setExample(String example) {
this.example = example;
}

public Details getDetails() {
return details;
}

public void setDetails(Details details) {
this.details = details;
}
}

Details.java

public class Details {

private Intro intro;
private Rest restObject;
private ArrayList<Rest> restList;

public Details(Intro intro, ArrayList<Rest> restList) {
this.intro = intro;
this.restList = restList;
}

public Details(Intro intro, Rest restObject) {
this.intro = intro;
this.restObject = restObject;
}

public Rest getRestObject() {
return restObject;
}

public ArrayList<Rest> getRestList() {
return restList;
}

public Intro getIntro() {
return intro;
}

public void setIntro(Intro intro) {
this.intro = intro;
}
}

Intro.java

public class Intro {

public Intro(String example) {
this.example = example;
}

private String example;

public String getExample() {
return example;
}

public void setExample(String example) {
this.example = example;
}

}

Rest.java

public class Rest {
private String example;

public Rest(String example) {
this.example = example;
}

public String getExample() {
return example;
}
}

关于java - 如何修复 "Expected BEGIN_OBJECT but was BEGIN_ARRAY"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57622603/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com