java - Expected BEGIN_OBJECT but was STRING with custom TypeAdapter -
so i'm trying solve problem have custom typeadapter gson , retrofit. keep getting expected begin_object string
error i'm not sure how solve it. getting expected begin_array string
error , solved that. i'm not sure if needs same way new error. i've listed classes below , appreciated. json looks here: http://pastie.org/private/bfo86iznldacbz10rtsdsg main problem multimedia field in json. it's empty string if there no value if there value, returns jsonarray contains jsonobjects.
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 new york times api // gets top stores on 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 classes
news.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 * status */ public string getstatus() { return status; } /** * * @param status * status */ public void setstatus(string status) { this.status = status; } /** * * @return * copyright */ public string getcopyright() { return copyright; } /** * * @param copyright * copyright */ public void setcopyright(string copyright) { this.copyright = copyright; } /** * * @return * numresults */ public integer getnumresults() { return numresults; } /** * * @param numresults * num_results */ public void setnumresults(integer numresults) { this.numresults = numresults; } /** * * @return * results */ public list<result> getresults() { return results; } /** * * @param results * results */ public void setresults(list<result> results) { this.results = results; } }
result.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 * section */ public string getsection() { return section; } /** * * @param section * section */ public void setsection(string section) { this.section = section; } /** * * @return * subsection */ public string getsubsection() { return subsection; } /** * * @param subsection * subsection */ public void setsubsection(string subsection) { this.subsection = subsection; } /** * * @return * title */ public string gettitle() { return title; } /** * * @param title * title */ public void settitle(string title) { this.title = title; } /** * * @return * _abstract */ public string getabstract() { return _abstract; } /** * * @param _abstract * abstract */ public void setabstract(string _abstract) { this._abstract = _abstract; } /** * * @return * url */ public string geturl() { return url; } /** * * @param url * url */ public void seturl(string url) { this.url = url; } /** * * @return * byline */ public string getbyline() { return byline; } /** * * @param byline * byline */ public void setbyline(string byline) { this.byline = byline; } /** * * @return * thumbnailstandard */ public string getthumbnailstandard() { return thumbnailstandard; } /** * * @param thumbnailstandard * thumbnail_standard */ public void setthumbnailstandard(string thumbnailstandard) { this.thumbnailstandard = thumbnailstandard; } /** * * @return * itemtype */ public string getitemtype() { return itemtype; } /** * * @param itemtype * item_type */ public void setitemtype(string itemtype) { this.itemtype = itemtype; } /** * * @return * source */ public string getsource() { return source; } /** * * @param source * source */ public void setsource(string source) { this.source = source; } /** * * @return * updateddate */ public string getupdateddate() { return updateddate; } /** * * @param updateddate * updated_date */ public void setupdateddate(string updateddate) { this.updateddate = updateddate; } /** * * @return * createddate */ public string getcreateddate() { return createddate; } /** * * @param createddate * created_date */ public void setcreateddate(string createddate) { this.createddate = createddate; } /** * * @return * publisheddate */ public string getpublisheddate() { return publisheddate; } /** * * @param publisheddate * published_date */ public void setpublisheddate(string publisheddate) { this.publisheddate = publisheddate; } /** * * @return * materialtypefacet */ public string getmaterialtypefacet() { return materialtypefacet; } /** * * @param materialtypefacet * material_type_facet */ public void setmaterialtypefacet(string materialtypefacet) { this.materialtypefacet = materialtypefacet; } /** * * @return * kicker */ public string getkicker() { return kicker; } /** * * @param kicker * kicker */ public void setkicker(string kicker) { this.kicker = kicker; } /** * * @return * subheadline */ public string getsubheadline() { return subheadline; } /** * * @param subheadline * subheadline */ public void setsubheadline(string subheadline) { this.subheadline = subheadline; } /** * * @return * desfacet */ public list<string> getdesfacet() { return desfacet; } /** * * @param desfacet * des_facet */ public void setdesfacet(list<string> desfacet) { this.desfacet = desfacet; } /** * * @return * orgfacet */ public list<string> getorgfacet() { return orgfacet; } /** * * @param orgfacet * org_facet */ public void setorgfacet(list<string> orgfacet) { this.orgfacet = orgfacet; } /** * * @return * perfacet */ public list<string> getperfacet() { return perfacet; } /** * * @param perfacet * per_facet */ public void setperfacet(list<string> perfacet) { this.perfacet = perfacet; } /** * * @return * geofacet */ public list<string> getgeofacet() { return geofacet; } /** * * @param geofacet * geo_facet */ public void setgeofacet(list<string> geofacet) { this.geofacet = geofacet; } /** * * @return * relatedurls */ public object getrelatedurls() { return relatedurls; } /** * * @param relatedurls * related_urls */ public void setrelatedurls(object relatedurls) { this.relatedurls = relatedurls; } /** * * @return * multimedia */ public list<multimedium> getmultimedia() { return multimedia; } /** * * @param multimedia * multimedia */ public void setmultimedia(list<multimedium> multimedia) { this.multimedia = multimedia; } }
multimedium.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 * url */ public string geturl() { return url; } /** * * @param url * url */ public void seturl(string url) { this.url = url; } /** * * @return * format */ public string getformat() { return format; } /** * * @param format * format */ public void setformat(string format) { this.format = format; } /** * * @return * height */ public integer getheight() { return height; } /** * * @param height * height */ public void setheight(integer height) { this.height = height; } /** * * @return * width */ public integer getwidth() { return width; } /** * * @param width * width */ public void setwidth(integer width) { this.width = width; } /** * * @return * type */ public string gettype() { return type; } /** * * @param type * type */ public void settype(string type) { this.type = type; } /** * * @return * subtype */ public string getsubtype() { return subtype; } /** * * @param subtype * subtype */ public void setsubtype(string subtype) { this.subtype = subtype; } /** * * @return * caption */ public object getcaption() { return caption; } /** * * @param caption * caption */ public void setcaption(object caption) { this.caption = caption; } /** * * @return * copyright */ public object getcopyright() { return copyright; } /** * * @param copyright * copyright */ public void setcopyright(object copyright) { this.copyright = copyright; } }
i know it's lot of code go through i'm looking solve problem i'm trying clear can.
i able solution implementing custom jsondeserializer
, adding restadapter
so:
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"); } } }
inside result.java
added following constructor (note can add more parameters things section, subsection, etc.):
public result(string title, multimedia ... multimedia) { this.mtitle = title.replace("\"", "");; mmultimedia = arrays.aslist(multimedia); }
then restadapter
following:
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(); }
i created custom application working , repository open sourced here:
this still of hackish solution, , feel not optimal, able following in time figured out solution:
Comments
Post a Comment