GSON 抛出“Expected String but was BEGIN_OBJECT”?
GSON throwing “Expected String but was BEGIN_OBJECT”?
乔森数据
{"response":{"status":"ok","userTier":"developer","total":1858191,"startIndex":1,"pageSize":10,"currentPage":1,"pages":185820,"orderBy":"newest","results":[{"type":"article","sectionId":"film","webTitle":"Open thread: what film do you regret watching when you were too young?","webPublicationDate":"2016-04-06T05:34:21Z","id":"film/2016/apr/06/open-thread-what-film-do-you-regret-watching-when-you-were-too-young","webUrl":"http://www.theguardian.com/film/2016/apr/06/open-thread-what-film-do-you-regret-watching-when-you-were-too-young","apiUrl":"http://content.guardianapis.com/film/2016/apr/06/open-thread-what-film-do-you-regret-watching-when-you-were-too-young","sectionName":"Film"},{"type":"article","sectionId":"travel","webTitle":"Sarajevo city guide: 10 of the best art and design-inspired destinations","webPublicationDate":"2016-04-06T05:30:29Z","id":"travel/2016/apr/06/sarajevo-city-guide-10-best-art-design-inspired-destinations","webUrl":"http://www.theguardian.com/travel/2016/apr/06/sarajevo-city-guide-10-best-art-design-inspired-destinations","apiUrl":"http://content.guardianapis.com/travel/2016/apr/06/sarajevo-city-guide-10-best-art-design-inspired-destinations","sectionName":"Travel"}]}}
Retrofit 2.0 调用
addNewUser.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Intent intent = new Intent(getApplicationContext(), ActivityNewUser.class);
//startActivity(intent);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://content.guardianapis.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
APIService service = retrofit.create(APIService.class);
Call<MyResponse> call = service.getNewsData();
call.enqueue(new Callback<MyResponse>() {
@Override
public void onResponse(Call<MyResponse> call1, Response<MyResponse> response) {
if (response.isSuccess()) {
Toast.makeText(getApplicationContext(), "success", Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(getApplicationContext(), "onResponse - something wrong" + response.message(), Toast.LENGTH_LONG).show();
}
// Get result Repo from response.body()
}
@Override
public void onFailure(Call<MyResponse> call1, Throwable t) {
Toast.makeText(getApplicationContext(), "exception: " + t.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
});
我的回复Class:
public class MyResponse {
String response;
public String getResponse() {
return response;
}
public void setResponse(String response) {
this.response = response;
}
}
通过异常进行改造调用:“预期的字符串但 BEGIN_OBJECT”?
谁能帮我看看为什么会出现这个异常?如何解决?
编辑:
我这样更改了 myResonse class:
public class MyResponse {
@Expose
@SerializedName("status")
String status;
List<Result> results;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public List<Result> getResults() {
return results;
}
public void setResults(List<Result> results) {
this.results = results;
}
}
结果class:
public class Result {
String type;
String sectionId;
String webTitle;
String webPublicationDate;
String id;
String webUrl;
String apiUrl;
String sectionName;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSectionId() {
return sectionId;
}
public void setSectionId(String sectionId) {
this.sectionId = sectionId;
}
public String getWebTitle() {
return webTitle;
}
public void setWebTitle(String webTitle) {
this.webTitle = webTitle;
}
public String getWebPublicationDate() {
return webPublicationDate;
}
public void setWebPublicationDate(String webPublicationDate) {
this.webPublicationDate = webPublicationDate;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getWebUrl() {
return webUrl;
}
public void setWebUrl(String webUrl) {
this.webUrl = webUrl;
}
public String getApiUrl() {
return apiUrl;
}
public void setApiUrl(String apiUrl) {
this.apiUrl = apiUrl;
}
public String getSectionName() {
return sectionName;
}
public void setSectionName(String sectionName) {
this.sectionName = sectionName;
}
}
和改装电话:
call.enqueue(new Callback<MyResponse>() {
@Override
public void onResponse(Call<MyResponse> call1, Response<MyResponse> response) {
if (response.isSuccess()) {
MyResponse myResponse = response.body();
Toast.makeText(getApplicationContext(), "" + myResponse.getResults().size(), Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(getApplicationContext(), "onResponse - something wrong" + response.message(), Toast.LENGTH_LONG).show();
}
// Get result Repo from response.body()
}
@Override
public void onFailure(Call<MyResponse> call1, Throwable t) {
Toast.makeText(getApplicationContext(), "exception: " + t.getMessage(), Toast.LENGTH_LONG).show();
}
});
这行报空指针异常
Toast.makeText(getApplicationContext(), "" + myResponse.getResults().size(), Toast.LENGTH_LONG).show();
如何修复它。
MyResponse 包含一个 STRING 类型的响应,而在 JSON 输出中,响应应该是一个对象。您必须创建自定义模型来解决此问题。
public class ResponseWrapper {
@SerializedName("response")
@Expose
private Response response; // There is a Custom Response Model
public Response getResponse() {
return response;
}
public void setResponse(Response response) {
this.response = response;
}
}
现在,使用 ResponseWrapper 而不是 MyResponse。您的响应模型应该是这样的:
public class Response {
@SerializedName("status")
@Expose
private String status;
@SerializedName("userTier")
@Expose
private String userTier;
.
.
.
.
// Write the rest of the entities
}
编辑
改变你的方法
public List<Result> getResults() {
return results;
}
收件人:
public ArrayList<Result> getResults() {
return results == null ? new ArrayList<>() : results;
}
如果使用片段,则将 getApplicationContext() 更改为 getActivity(),或者 ACTIVITYNAME.this,如:
Toast.makeText(getActivity(), "" + myResponse.getResults().size(), Toast.LENGTH_LONG).show();
像下面这样制作一个Response
class然后用GSON
解析
public class Response {
@Expose
@SerializedName("status")
String status;
public String getstatus() {
return this.status;
}
public void setstatus(String status) {
this.status = status;
}
@Expose
public List<Result> results = new ArrayList<Result>();
public List<Result> getResults () {
return results ;
}
public void setResults(ArrayList<Result> results ) {
this.results = results ;
}
//Make getter and setter for each and every fields in your JSON that you want
}
因为 results
和 JSONArray
在你的 JSON 所以你必须把 Result
作为另一个模型并添加在主要class喜欢
public class Result{
@Expose
@SerializedName("type")
String type;
public String gettype() {
return this.type;
}
public void settype(String type) {
this.type= type;
}
//Make getter and setter for each and every fields in your JSON that you want
}
乔森数据
{"response":{"status":"ok","userTier":"developer","total":1858191,"startIndex":1,"pageSize":10,"currentPage":1,"pages":185820,"orderBy":"newest","results":[{"type":"article","sectionId":"film","webTitle":"Open thread: what film do you regret watching when you were too young?","webPublicationDate":"2016-04-06T05:34:21Z","id":"film/2016/apr/06/open-thread-what-film-do-you-regret-watching-when-you-were-too-young","webUrl":"http://www.theguardian.com/film/2016/apr/06/open-thread-what-film-do-you-regret-watching-when-you-were-too-young","apiUrl":"http://content.guardianapis.com/film/2016/apr/06/open-thread-what-film-do-you-regret-watching-when-you-were-too-young","sectionName":"Film"},{"type":"article","sectionId":"travel","webTitle":"Sarajevo city guide: 10 of the best art and design-inspired destinations","webPublicationDate":"2016-04-06T05:30:29Z","id":"travel/2016/apr/06/sarajevo-city-guide-10-best-art-design-inspired-destinations","webUrl":"http://www.theguardian.com/travel/2016/apr/06/sarajevo-city-guide-10-best-art-design-inspired-destinations","apiUrl":"http://content.guardianapis.com/travel/2016/apr/06/sarajevo-city-guide-10-best-art-design-inspired-destinations","sectionName":"Travel"}]}}
Retrofit 2.0 调用
addNewUser.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Intent intent = new Intent(getApplicationContext(), ActivityNewUser.class);
//startActivity(intent);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://content.guardianapis.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
APIService service = retrofit.create(APIService.class);
Call<MyResponse> call = service.getNewsData();
call.enqueue(new Callback<MyResponse>() {
@Override
public void onResponse(Call<MyResponse> call1, Response<MyResponse> response) {
if (response.isSuccess()) {
Toast.makeText(getApplicationContext(), "success", Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(getApplicationContext(), "onResponse - something wrong" + response.message(), Toast.LENGTH_LONG).show();
}
// Get result Repo from response.body()
}
@Override
public void onFailure(Call<MyResponse> call1, Throwable t) {
Toast.makeText(getApplicationContext(), "exception: " + t.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
});
我的回复Class:
public class MyResponse {
String response;
public String getResponse() {
return response;
}
public void setResponse(String response) {
this.response = response;
}
}
通过异常进行改造调用:“预期的字符串但 BEGIN_OBJECT”?
谁能帮我看看为什么会出现这个异常?如何解决?
编辑:
我这样更改了 myResonse class:
public class MyResponse {
@Expose
@SerializedName("status")
String status;
List<Result> results;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public List<Result> getResults() {
return results;
}
public void setResults(List<Result> results) {
this.results = results;
}
}
结果class:
public class Result {
String type;
String sectionId;
String webTitle;
String webPublicationDate;
String id;
String webUrl;
String apiUrl;
String sectionName;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSectionId() {
return sectionId;
}
public void setSectionId(String sectionId) {
this.sectionId = sectionId;
}
public String getWebTitle() {
return webTitle;
}
public void setWebTitle(String webTitle) {
this.webTitle = webTitle;
}
public String getWebPublicationDate() {
return webPublicationDate;
}
public void setWebPublicationDate(String webPublicationDate) {
this.webPublicationDate = webPublicationDate;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getWebUrl() {
return webUrl;
}
public void setWebUrl(String webUrl) {
this.webUrl = webUrl;
}
public String getApiUrl() {
return apiUrl;
}
public void setApiUrl(String apiUrl) {
this.apiUrl = apiUrl;
}
public String getSectionName() {
return sectionName;
}
public void setSectionName(String sectionName) {
this.sectionName = sectionName;
}
}
和改装电话:
call.enqueue(new Callback<MyResponse>() {
@Override
public void onResponse(Call<MyResponse> call1, Response<MyResponse> response) {
if (response.isSuccess()) {
MyResponse myResponse = response.body();
Toast.makeText(getApplicationContext(), "" + myResponse.getResults().size(), Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(getApplicationContext(), "onResponse - something wrong" + response.message(), Toast.LENGTH_LONG).show();
}
// Get result Repo from response.body()
}
@Override
public void onFailure(Call<MyResponse> call1, Throwable t) {
Toast.makeText(getApplicationContext(), "exception: " + t.getMessage(), Toast.LENGTH_LONG).show();
}
});
这行报空指针异常
Toast.makeText(getApplicationContext(), "" + myResponse.getResults().size(), Toast.LENGTH_LONG).show();
如何修复它。
MyResponse 包含一个 STRING 类型的响应,而在 JSON 输出中,响应应该是一个对象。您必须创建自定义模型来解决此问题。
public class ResponseWrapper {
@SerializedName("response")
@Expose
private Response response; // There is a Custom Response Model
public Response getResponse() {
return response;
}
public void setResponse(Response response) {
this.response = response;
}
}
现在,使用 ResponseWrapper 而不是 MyResponse。您的响应模型应该是这样的:
public class Response {
@SerializedName("status")
@Expose
private String status;
@SerializedName("userTier")
@Expose
private String userTier;
.
.
.
.
// Write the rest of the entities
}
编辑
改变你的方法
public List<Result> getResults() {
return results;
}
收件人:
public ArrayList<Result> getResults() {
return results == null ? new ArrayList<>() : results;
}
如果使用片段,则将 getApplicationContext() 更改为 getActivity(),或者 ACTIVITYNAME.this,如:
Toast.makeText(getActivity(), "" + myResponse.getResults().size(), Toast.LENGTH_LONG).show();
像下面这样制作一个Response
class然后用GSON
解析
public class Response {
@Expose
@SerializedName("status")
String status;
public String getstatus() {
return this.status;
}
public void setstatus(String status) {
this.status = status;
}
@Expose
public List<Result> results = new ArrayList<Result>();
public List<Result> getResults () {
return results ;
}
public void setResults(ArrayList<Result> results ) {
this.results = results ;
}
//Make getter and setter for each and every fields in your JSON that you want
}
因为 results
和 JSONArray
在你的 JSON 所以你必须把 Result
作为另一个模型并添加在主要class喜欢
public class Result{
@Expose
@SerializedName("type")
String type;
public String gettype() {
return this.type;
}
public void settype(String type) {
this.type= type;
}
//Make getter and setter for each and every fields in your JSON that you want
}