gpt4 book ai didi

java - 应为 BEGIN_OBJECT 但为带有自定义 TypeAdapter 的 STRING

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

因此,我正在尝试使用 Gson 和 Retrofit 解决我的自定义 TypeAdapter 遇到的问题。我一直收到 Expected BEGIN_OBJECT but was STRING 错误,但我不确定如何解决它。以前我收到一个 Expected BEGIN_ARRAY but was STRING 错误,我解决了这个问题。我不确定这个新错误是否需要采用相同的方式。我在下面列出了我的类(class),我们将不胜感激。这就是我的 json 在这里的样子:http://pastie.org/private/bfo86iznldacbz10rtsdsg主要问题是json中的多媒体字段。如果没有值,它是一个空字符串,但如果有值,它返回一个包含 jsonobjects 的 jsonarray。

ArrayAdapter.java

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;


public class ArrayAdapter<T> extends TypeAdapter<List<T>> {
private Class<T> adapterclass;

public ArrayAdapter(Class<T> adapterclass) {
this.adapterclass = adapterclass;
}

public List<T> read(JsonReader reader) throws IOException {

List<T> list = new ArrayList<T>();

Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new ArrayAdapterFactory())
.create();

if (reader.peek() == JsonToken.STRING) {
T inning = gson.fromJson(reader, adapterclass);
list.add(inning);
} else if (reader.peek() == JsonToken.BEGIN_ARRAY) {

reader.beginArray();
while (reader.hasNext()) {
T inning = gson.fromJson(reader, adapterclass);
list.add(inning);
}
reader.endArray();

} else if (reader.peek() == JsonToken.BEGIN_OBJECT) {
reader.beginObject();
while(reader.hasNext()) {
}
}

return list;
}

public void write(JsonWriter writer, List<T> value) throws IOException {

}

}

ArraryAdapterFactory

import java.lang.reflect.ParameterizedType;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;

public class ArrayAdapterFactory implements TypeAdapterFactory {

@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {

TypeAdapter<T> typeAdapter = null;

try {
if (type.getRawType() == List.class)
typeAdapter = new ArrayAdapter(
(Class) ((ParameterizedType) type.getType())
.getActualTypeArguments()[0]);
} catch (Exception e) {
e.printStackTrace();
}

return typeAdapter;


}

}

Times.java

public class NYTimes {

// uses the new york times api
// gets the top stores on the nytimes homepage
private static final String API_URL = "http://api.nytimes.com/svc/news/v3/content/all/all";

static Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ArrayAdapterFactory()).create();

private static final RestAdapter REST_ADAPTER = new RestAdapter.Builder()
.setConverter(new GsonConverter(gson))
.setEndpoint(API_URL)
.build();

private static final NYTimesService SERVICE = REST_ADAPTER.create(NYTimesService.class);

public static NYTimesService getService() {
return SERVICE;
}
}

POJO 类

新闻.java

public class News {

@Expose
private String status;
@Expose
private String copyright;
@SerializedName("num_results")
@Expose
private Integer numResults;
@Expose
private List<Result> results = new ArrayList<Result>();

/**
*
* @return
* The status
*/
public String getStatus() {
return status;
}

/**
*
* @param status
* The status
*/
public void setStatus(String status) {
this.status = status;
}

/**
*
* @return
* The copyright
*/
public String getCopyright() {
return copyright;
}

/**
*
* @param copyright
* The copyright
*/
public void setCopyright(String copyright) {
this.copyright = copyright;
}

/**
*
* @return
* The numResults
*/
public Integer getNumResults() {
return numResults;
}

/**
*
* @param numResults
* The num_results
*/
public void setNumResults(Integer numResults) {
this.numResults = numResults;
}

/**
*
* @return
* The results
*/
public List<Result> getResults() {
return results;
}

/**
*
* @param results
* The results
*/
public void setResults(List<Result> results) {
this.results = results;
}

}

结果.java

public class Result {
@Expose
private String section;
@Expose
private String subsection;
@Expose
private String title;
@SerializedName("abstract")
@Expose
private String _abstract;
@Expose
private String url;
@Expose
private String byline;
@SerializedName("thumbnail_standard")
@Expose
private String thumbnailStandard;
@SerializedName("item_type")
@Expose
private String itemType;
@Expose
private String source;
@SerializedName("updated_date")
@Expose
private String updatedDate;
@SerializedName("created_date")
@Expose
private String createdDate;
@SerializedName("published_date")
@Expose
private String publishedDate;
@SerializedName("material_type_facet")
@Expose
private String materialTypeFacet;
@Expose
private String kicker;
@Expose
private String subheadline;
@SerializedName("des_facet")
@Expose
private List<String> desFacet = new ArrayList<>();
@SerializedName("org_facet")
@Expose
private List<String> orgFacet = new ArrayList<>();
@SerializedName("per_facet")
@Expose
private List<String> perFacet = new ArrayList<>();
@SerializedName("geo_facet")
@Expose
private List<String> geoFacet = new ArrayList<>();
@SerializedName("related_urls")
@Expose
private Object relatedUrls;
@Expose
private List<Multimedium> multimedia;

/**
*
* @return
* The section
*/
public String getSection() {
return section;
}

/**
*
* @param section
* The section
*/
public void setSection(String section) {
this.section = section;
}

/**
*
* @return
* The subsection
*/
public String getSubsection() {
return subsection;
}

/**
*
* @param subsection
* The subsection
*/
public void setSubsection(String subsection) {
this.subsection = subsection;
}

/**
*
* @return
* The title
*/
public String getTitle() {
return title;
}

/**
*
* @param title
* The title
*/
public void setTitle(String title) {
this.title = title;
}

/**
*
* @return
* The _abstract
*/
public String getAbstract() {
return _abstract;
}

/**
*
* @param _abstract
* The abstract
*/
public void setAbstract(String _abstract) {
this._abstract = _abstract;
}

/**
*
* @return
* The url
*/
public String getUrl() {
return url;
}

/**
*
* @param url
* The url
*/
public void setUrl(String url) {
this.url = url;
}

/**
*
* @return
* The byline
*/
public String getByline() {
return byline;
}

/**
*
* @param byline
* The byline
*/
public void setByline(String byline) {
this.byline = byline;
}

/**
*
* @return
* The thumbnailStandard
*/
public String getThumbnailStandard() {
return thumbnailStandard;
}

/**
*
* @param thumbnailStandard
* The thumbnail_standard
*/
public void setThumbnailStandard(String thumbnailStandard) {
this.thumbnailStandard = thumbnailStandard;
}

/**
*
* @return
* The itemType
*/
public String getItemType() {
return itemType;
}

/**
*
* @param itemType
* The item_type
*/
public void setItemType(String itemType) {
this.itemType = itemType;
}

/**
*
* @return
* The source
*/
public String getSource() {
return source;
}

/**
*
* @param source
* The source
*/
public void setSource(String source) {
this.source = source;
}

/**
*
* @return
* The updatedDate
*/
public String getUpdatedDate() {
return updatedDate;
}

/**
*
* @param updatedDate
* The updated_date
*/
public void setUpdatedDate(String updatedDate) {
this.updatedDate = updatedDate;
}

/**
*
* @return
* The createdDate
*/
public String getCreatedDate() {
return createdDate;
}

/**
*
* @param createdDate
* The created_date
*/
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}

/**
*
* @return
* The publishedDate
*/
public String getPublishedDate() {
return publishedDate;
}

/**
*
* @param publishedDate
* The published_date
*/
public void setPublishedDate(String publishedDate) {
this.publishedDate = publishedDate;
}

/**
*
* @return
* The materialTypeFacet
*/
public String getMaterialTypeFacet() {
return materialTypeFacet;
}

/**
*
* @param materialTypeFacet
* The material_type_facet
*/
public void setMaterialTypeFacet(String materialTypeFacet) {
this.materialTypeFacet = materialTypeFacet;
}

/**
*
* @return
* The kicker
*/
public String getKicker() {
return kicker;
}

/**
*
* @param kicker
* The kicker
*/
public void setKicker(String kicker) {
this.kicker = kicker;
}

/**
*
* @return
* The subheadline
*/
public String getSubheadline() {
return subheadline;
}

/**
*
* @param subheadline
* The subheadline
*/
public void setSubheadline(String subheadline) {
this.subheadline = subheadline;
}

/**
*
* @return
* The desFacet
*/
public List<String> getDesFacet() {
return desFacet;
}

/**
*
* @param desFacet
* The des_facet
*/
public void setDesFacet(List<String> desFacet) {
this.desFacet = desFacet;
}

/**
*
* @return
* The orgFacet
*/
public List<String> getOrgFacet() {
return orgFacet;
}

/**
*
* @param orgFacet
* The org_facet
*/
public void setOrgFacet(List<String> orgFacet) {
this.orgFacet = orgFacet;
}

/**
*
* @return
* The perFacet
*/
public List<String> getPerFacet() {
return perFacet;
}

/**
*
* @param perFacet
* The per_facet
*/
public void setPerFacet(List<String> perFacet) {
this.perFacet = perFacet;
}

/**
*
* @return
* The geoFacet
*/
public List<String> getGeoFacet() {
return geoFacet;
}

/**
*
* @param geoFacet
* The geo_facet
*/
public void setGeoFacet(List<String> geoFacet) {
this.geoFacet = geoFacet;
}

/**
*
* @return
* The relatedUrls
*/
public Object getRelatedUrls() {
return relatedUrls;
}

/**
*
* @param relatedUrls
* The related_urls
*/
public void setRelatedUrls(Object relatedUrls) {
this.relatedUrls = relatedUrls;
}

/**
*
* @return
* The multimedia
*/
public List<Multimedium> getMultimedia() {
return multimedia;
}

/**
*
* @param multimedia
* The multimedia
*/
public void setMultimedia(List<Multimedium> multimedia) {
this.multimedia = multimedia;
}
}

多媒体.java

public class Multimedium {
@Expose
private String url;
@Expose
private String format;
@Expose
private Integer height;
@Expose
private Integer width;
@Expose
private String type;
@Expose
private String subtype;
@Expose
private Object caption;
@Expose
private Object copyright;

/**
*
* @return
* The url
*/
public String getUrl() {
return url;
}

/**
*
* @param url
* The url
*/
public void setUrl(String url) {
this.url = url;
}

/**
*
* @return
* The format
*/
public String getFormat() {
return format;
}

/**
*
* @param format
* The format
*/
public void setFormat(String format) {
this.format = format;
}

/**
*
* @return
* The height
*/
public Integer getHeight() {
return height;
}

/**
*
* @param height
* The height
*/
public void setHeight(Integer height) {
this.height = height;
}

/**
*
* @return
* The width
*/
public Integer getWidth() {
return width;
}

/**
*
* @param width
* The width
*/
public void setWidth(Integer width) {
this.width = width;
}

/**
*
* @return
* The type
*/
public String getType() {
return type;
}

/**
*
* @param type
* The type
*/
public void setType(String type) {
this.type = type;
}

/**
*
* @return
* The subtype
*/
public String getSubtype() {
return subtype;
}

/**
*
* @param subtype
* The subtype
*/
public void setSubtype(String subtype) {
this.subtype = subtype;
}

/**
*
* @return
* The caption
*/
public Object getCaption() {
return caption;
}

/**
*
* @param caption
* The caption
*/
public void setCaption(Object caption) {
this.caption = caption;
}

/**
*
* @return
* The copyright
*/
public Object getCopyright() {
return copyright;
}

/**
*
* @param copyright
* The copyright
*/
public void setCopyright(Object copyright) {
this.copyright = copyright;
}
}

我知道有很多代码要处理,但我正在寻找任何帮助来解决这个问题,所以我尽量说得清楚。

最佳答案

我能够通过实现自定义 JsonDeserializer 然后将其添加到 RestAdapter 来获得解决方案,如下所示:

public class ResultsDeserializerJson implements JsonDeserializer<Result> {

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

JsonElement titleElement = json.getAsJsonObject().get("title");
JsonElement multimediaElement = json.getAsJsonObject().get("multimedia");
if (multimediaElement.isJsonArray()) {
return new Result(
titleElement.toString(),
(Multimedia[]) context.deserialize(multimediaElement.getAsJsonArray(), Multimedia[].class));
} else if (multimediaElement.getAsString().equals("")) {
Multimedia multimedia = new Multimedia();
multimedia.setFormat("");
multimedia.setUrl("");
return new Result(titleElement.toString(), multimedia);
} else {
Log.d("ResultsDeserializerJson", multimediaElement.toString());
throw new JsonParseException("Unsupported type of multimedia element");
}
}
}

Result.java 中,我添加了以下构造函数(请注意,您可以为部分、子部分等添加更多参数):

public Result(String title, Multimedia ... multimedia) {
this.mTitle = title.replace("\"", "");;
mMultimedia = Arrays.asList(multimedia);
}

然后,对于我的 RestAdapter,我执行以下操作:

private NYTimesService() {

Gson gson = new GsonBuilder()
.registerTypeAdapter(Result.class, new ResultsDeserializerJson()).create();

mAsyncRestAdapter = new RestAdapter.Builder()
.setEndpoint(API_URL)
.setConverter(new GsonConverter(gson))
.setRequestInterceptor(new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
request.addEncodedQueryParam("api-key", API_KEY);
}
})
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
}

我创建了一个自定义应用程序来让它工作,并且存储库在此处开源:

SampleNYTimesApp Repo

这仍然是一个有点 hackish 的解决方案,我觉得它不是最优的,但是在我找到解决方案的时候我能够得到以下结果:

enter image description here

关于java - 应为 BEGIN_OBJECT 但为带有自定义 TypeAdapter 的 STRING,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31173817/

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