gpt4 book ai didi

android - Retrofit 2.0 的自定义类型适配器

转载 作者:太空狗 更新时间:2023-10-29 15:25:26 24 4
gpt4 key购买 nike

我使用的 API 提供了我需要的更多信息。我正在使用 Retrofit 和 GSON 获取数据并创建具有所需值的 POJO 列表。我制作了一个自定义 TypeAdapter,在其中,我得到了响应并返回了一个对象列表。使用本地 JSON 对象时,自定义 TypeAdapter 可以正常工作,但使用 Retrofit 时我会出错。

Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

知道这是为什么吗?我做错了什么?

编辑:

我更改了 GsonBuilder,将正确的类型传递给 Retrofit Builder,如下所示:

Type collectionType = new TypeToken<List<Article>>(){}.getType();
gsonBuilder.registerTypeAdapter(collectionType,new ArticleTypeAdapter());

JSON

{
"status": "OK",
"copyright": "Copyright (c) 2017 The New York Times Company. All Rights Reserved.",
"num_results": 5,
"results": [
{
"url": "https://www.nytimes.com/2017/06/29/automobiles/autoreviews/video-review-a-family-friendly-ferrari-for-the-family-of-means.html",
"adx_keywords": "Ferrari SpA;Ferrari GTC4Lusso;Automobiles",
"column": "Driven",
"section": "Automobiles",
"byline": "By TOM VOELK",
"type": "Article",
"title": "Video Review: A Family-Friendly Ferrari, for the Family of Means",
"abstract": "The all-wheel-drive V12 GTC4Lusso seats four comfortably. With its svelte silhouette, it may look like a station wagon. It is anything but.",
"published_date": "2017-06-29",
"source": "The New York Times",
"id": 100000005178442,
"asset_id": 100000005178442,
"views": 1,
"des_facet": [
"AUTOMOBILES"
],
"org_facet": [
"FERRARI SPA"
],
"per_facet": "",
"geo_facet": "",
"media": [
{
"type": "image",
"subtype": "photo",
"caption": "Ferrari GTC4Lusso",
"copyright": "Martin Campbell",
"approved_for_syndication": 1,
"media-metadata": [
{
"url": "https://static01.nyt.com/images/2017/06/26/automobiles/autoreviews/27driven1/27driven1-thumbStandard.jpg",
"format": "Standard Thumbnail",
"height": 75,
"width": 75
},
{
"url": "https://static01.nyt.com/images/2017/06/26/automobiles/autoreviews/27driven1/27driven1-mediumThreeByTwo210.jpg",
"format": "mediumThreeByTwo210",
"height": 140,
"width": 210
},
{
"url": "https://static01.nyt.com/images/2017/06/26/automobiles/autoreviews/27driven1/27driven1-mediumThreeByTwo440.jpg",
"format": "mediumThreeByTwo440",
"height": 293,
"width": 440
}
]
}
]
},
{
"url": "https://www.nytimes.com/2017/07/06/automobiles/wheels/luxury-cars-dealers-sales.html",
"adx_keywords": "Automobiles;Luxury Goods and Services;Customer Relations;United States;Lexus Division of Toyota Motor Corp;Cadillac Division of General Motors Corp;Alfa Romeo Automobiles;Lincoln Motor Co",
"column": "Wheels",
"section": "Automobiles",
"byline": "By ERIC A. TAUB",
"type": "Article",
"title": "How to Soothe Luxury-Car Buyers: Add Perks and Subtract Haggling",
"abstract": "Several automakers aim to change the shopping experience with fixed prices, after-sale care and even ways to avoid the dealership altogether.",
"published_date": "2017-07-06",
"source": "The New York Times",
"id": 100000005135624,
"asset_id": 100000005135624,
"views": 2,
"des_facet": [
"AUTOMOBILES",
"LUXURY GOODS AND SERVICES",
"CUSTOMER RELATIONS"
],
"org_facet": [
"LEXUS DIVISION OF TOYOTA MOTOR CORP",
"CADILLAC DIVISION OF GENERAL MOTORS CORP",
"ALFA ROMEO AUTOMOBILES",
"LINCOLN MOTOR CO"
],
"per_facet": "",
"geo_facet": [
"UNITED STATES"
],
"media": [
{
"type": "image",
"subtype": "photo",
"caption": "Lexus has introduced a fixed-price program, called Lexus Plus, in which the buyer deals with only one person from beginning to end.",
"copyright": "Alex Wroblewski for The New York Times",
"approved_for_syndication": 1,
"media-metadata": [
{
"url": "https://static01.nyt.com/images/2017/07/06/business/07WHEELS1/07WHEELS1-thumbStandard.jpg",
"format": "Standard Thumbnail",
"height": 75,
"width": 75
},
{
"url": "https://static01.nyt.com/images/2017/07/06/business/07WHEELS1/07WHEELS1-mediumThreeByTwo210.jpg",
"format": "mediumThreeByTwo210",
"height": 140,
"width": 210
},
{
"url": "https://static01.nyt.com/images/2017/07/06/business/07WHEELS1/07WHEELS1-mediumThreeByTwo440.jpg",
"format": "mediumThreeByTwo440",
"height": 293,
"width": 440
}
]
}
]
},
{
"url": "https://www.nytimes.com/2017/06/29/automobiles/wheels/why-fog-lamps-are-starting-to-disappear.html",
"adx_keywords": "Automobile Safety Features and Defects;AAA Foundation for Traffic Safety;Mercedes-Benz;Consumer Reports;Insurance Institute for Highway Safety",
"column": "Wheels",
"section": "Automobiles",
"byline": "By JAMES G. COBB",
"type": "Article",
"title": "Why Fog Lamps Are Starting to Disappear",
"abstract": "Several luxury automakers have moved away from fog lights, saying that new high-tech headlights render them obsolete.",
"published_date": "2017-06-29",
"source": "The New York Times",
"id": 100000005172500,
"asset_id": 100000005172500,
"views": 3,
"des_facet": [
"AUTOMOBILE SAFETY FEATURES AND DEFECTS"
],
"org_facet": [
"AAA FOUNDATION FOR TRAFFIC SAFETY",
"MERCEDES-BENZ",
"CONSUMER REPORTS",
"INSURANCE INSTITUTE FOR HIGHWAY SAFETY"
],
"per_facet": "",
"geo_facet": "",
"media": [
{
"type": "image",
"subtype": "photo",
"caption": "General Motors’ headquarters and other buildings in the Detroit skyline, obscured by early morning fog. Some automakers have quietly omitted front fog lights from many new models, saying that high-tech headlights make them unnecessary.",
"copyright": "Kevin Miyazaki for The New York Times",
"approved_for_syndication": 1,
"media-metadata": [
{
"url": "https://static01.nyt.com/images/2017/06/29/business/30WHEELS1/30WHEELS1-thumbStandard.jpg",
"format": "Standard Thumbnail",
"height": 75,
"width": 75
},
{
"url": "https://static01.nyt.com/images/2017/06/29/business/30WHEELS1/30WHEELS1-mediumThreeByTwo210.jpg",
"format": "mediumThreeByTwo210",
"height": 140,
"width": 210
},
{
"url": "https://static01.nyt.com/images/2017/06/29/business/30WHEELS1/30WHEELS1-mediumThreeByTwo440.jpg",
"format": "mediumThreeByTwo440",
"height": 293,
"width": 440
}
]
}
]
},
{
"url": "https://www.nytimes.com/2017/07/06/automobiles/autoreviews/video-review-volvo-v90-cross-country-rolls-into-suv-territory.html",
"adx_keywords": "Automobiles;Volvo Car Corp;2017 Volvo V90 Cross Country",
"column": "Driven",
"section": "Automobiles",
"byline": "By TOM VOELK",
"type": "Article",
"title": "Video Review: Volvo V90 Cross Country Rolls Into S.U.V. Territory",
"abstract": "Americans are buying S.U.V.s and crossovers in record numbers, but it’s worth keeping an open mind about Volvo’s station wagon.",
"published_date": "2017-07-06",
"source": "The New York Times",
"id": 100000005194798,
"asset_id": 100000005194798,
"views": 4,
"des_facet": [
"AUTOMOBILES"
],
"org_facet": [
"VOLVO CAR CORP"
],
"per_facet": "",
"geo_facet": "",
"media": ""
},
{
"url": "https://www.nytimes.com/2017/06/08/automobiles/saab-autos-cars.html",
"adx_keywords": "Automobiles;Saab Automobile AB;Bankruptcies;Portland (Ore)",
"column": "Wheels",
"section": "Automobiles",
"byline": "By NICK KURCZEWSKI",
"type": "Article",
"title": "In Portland, a Rare Outpost for Die-Hard Saab Fans",
"abstract": "The Swedish automaker filed for bankruptcy in 2011, leaving a vanishingly small number of dealerships for fans of the company.",
"published_date": "2017-06-08",
"source": "The New York Times",
"id": 100000005095241,
"asset_id": 100000005095241,
"views": 5,
"des_facet": [
"AUTOMOBILES",
"BANKRUPTCIES"
],
"org_facet": [
"SAAB AUTOMOBILE AB"
],
"per_facet": "",
"geo_facet": [
"PORTLAND (ORE)"
],
"media": [
{
"type": "image",
"subtype": "photo",
"caption": "Saab filed for bankruptcy in 2011, but Garry Small Saab in Portland, Ore., has continued to service and sell the brand’s cars.",
"copyright": "Amanda Lucier for The New York Times",
"approved_for_syndication": 1,
"media-metadata": [
{
"url": "https://static01.nyt.com/images/2017/06/08/business/09WHEELS1/09WHEELS1-thumbStandard.jpg",
"format": "Standard Thumbnail",
"height": 75,
"width": 75
},
{
"url": "https://static01.nyt.com/images/2017/06/08/business/09WHEELS1/09WHEELS1-mediumThreeByTwo210.jpg",
"format": "mediumThreeByTwo210",
"height": 140,
"width": 210
},
{
"url": "https://static01.nyt.com/images/2017/06/08/business/09WHEELS1/09WHEELS1-mediumThreeByTwo440.jpg",
"format": "mediumThreeByTwo440",
"height": 293,
"width": 440
}
]
}
]
}
]

Type Adapter的读取方法

public List<Article> read(JsonReader in) throws IOException {

final List<Article> article_list = new ArrayList<>();
in.beginObject();
while(in.hasNext()){
switch (in.nextName()){
case "results":
in.beginArray();
while(in.hasNext()){
final Article article = new Article();
in.beginObject();
while (in.hasNext()){
switch (in.nextName()){

case "id":
article.setId(Long.valueOf(in.nextString()));
break;
case "title":
article.setTitle(in.nextString());
break;
case "url":
article.setUrl(in.nextString());
break;
case "adx_keywords":
article.setAdxKeywords(in.nextString());
break;
case "section":
article.setSection(in.nextString());
break;
case "byline":
article.setByline(in.nextString());
break;
case "abstract":
article.set_abstract(in.nextString());
break;
case "published_date":
article.setPublishedDate(in.nextString());
break;
case "media":
if(!in.peek().equals(JsonToken.BEGIN_ARRAY)){
in.skipValue();
break;
}
in.beginArray();
final ArrayList<Media> media_list = new ArrayList<>();
while(in.hasNext()){
in.beginObject();
while(in.hasNext()){
switch (in.nextName()){
case "media-metadata":
in.beginArray();
while(in.hasNext()){
in.beginObject();
final Media media = new Media();
while(in.hasNext()){
switch (in.nextName()){
case "url":
media.setUrl(in.nextString());
break;
case "format":
media.setFormat(in.nextString());
break;
default:
in.skipValue();
break;
}
}
in.endObject();
media_list.add(media);
}
in.endArray();
break;
default:
in.skipValue();
break;
}
}
in.endObject();
}
in.endArray();
for(Media m : media_list){
if(m.getFormat().equals("mediumThreeByTwo440")){
article.setMedia(m);
break;
}
}
break;

default:
in.skipValue();
break;
}/**/
}
in.endObject();
article_list.add(article);
}
in.endArray();
break;
default:
in.skipValue();
break;

}

}
in.endObject();

Timber.d(article_list.toString());
return article_list;
}

文章和媒体类(无方法)

public class Article {
private Long id;
private String url;
private String adxKeywords;
private String section;
private String byline;
private String title;
private String _abstract;
private String publishedDate;
private Media media;
}

public class Media {
private String url;
private String format;
}

改造生成器

final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Article.class,new ArticleTypeAdapter());
final Gson gson = gsonBuilder.create();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();

最佳答案

你需要做这样的事情:-

public class Response{
public String status;
public String copyright;
public int num_results;
public Article[] results;
}

您必须传递一个与您从服务器接收到的响应结构相同的响应类。请按照以下步骤操作:-

您不需要为每个请求使用不同类型的适配器,您可以像这样使用默认的 Gson 转换器工厂简单地创建改造:-

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

现在您需要像这样为 API 请求定义一个服务:-

public class ArticleService{
@GET("endpoint")//What ever is your request type
Call<Response> getArticals(/** body query param or other required data**// )
}

之后你请求创建将是这样的:-

ArticleService service = retrofit.create(ArticleService.class);

关于android - Retrofit 2.0 的自定义类型适配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44962386/

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