简体   繁体   English

如何在Android中使用GSON解析JSON

[英]How to parse JSON using GSON in android

I am developing an application where I want to hit the web services and get the data. 我正在开发一个应用程序,我想在该应用程序上访问Web服务并获取数据。 I am using Google Volley to hit the web service. 我正在使用Google Volley来访问Web服务。 I am doing it all right but unable to parse JSON using GSON . 我做的很好,但是无法使用GSON解析JSON I am unable to understand where I am doing it wrong. 我无法理解我在哪里做错了。

Here is the URL of Web Services 这是Web服务的URL

Here is what I am doing 这是我在做什么

    RequestQueue requestQueue = Volley.newRequestQueue(this);
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
            Request.Method.GET,
            "https://api.github.com/repos/crashlytics/secureudid/issues",
            null,
            new MyListner(),
            new MyErrorListner()
    );

    requestQueue.add(jsonObjectRequest);

}

class MyListner implements Response.Listener<JSONObject>
{
    @Override
    public void onResponse(JSONObject response) {

        Gson gson = new Gson();
        Results results = gson.fromJson(response.toString(), Results.class);

        for(Test t : results.getmResults())
        {
            Log.e("Tag", t.toString());
        }


    }
}

class MyErrorListner implements Response.ErrorListener
{
    @Override
    public void onErrorResponse(VolleyError error) {
        Log.e("Error", error.getMessage());
    }
}

The other classes are given below 其他课程如下

public class Results {


private ArrayList<Test> mResults;

public void setResults(ArrayList<Test> results)
{
    mResults = results;
}

public ArrayList<Test> getmResults()
{
    return mResults;
}
}

public class Test {

@SerializedName("title")
private String mTitle;

@SerializedName("user")
private User mUser;

@SerializedName("created_at")
private String mCreatedAt;

@SerializedName("body")
private String mBody;

@SerializedName("updated_at")
private String mUpdatedAt;

public String getmBody() {
    return mBody;
}

public void setmBody(String mBody) {
    this.mBody = mBody;
}

public String getmUpdatedAt() {
    return mUpdatedAt;
}

public void setmUpdatedAt(String mUpdatedAt) {
    this.mUpdatedAt = mUpdatedAt;
}

public String getmCreatedAt() {
    return mCreatedAt;
}

public void setmCreatedAt(String mCreatedAt) {
    this.mCreatedAt = mCreatedAt;
}

public User getmUser() {
    return mUser;
}

public void setmUser(User mUser) {
    this.mUser = mUser;
}

public String getmTitle() {
    return mTitle;
}

public void setmTitle(String mTitle) {
    this.mTitle = mTitle;
}

@Override
public String toString() {
    return mTitle + " " + mBody + " " + mCreatedAt + " " + mUpdatedAt + " " + mUser.getmLogin() + " ";
}
}


public class User {

@SerializedName("login")
private String mLogin;

public String getmLogin() {
    return mLogin;
}

public void setmLogin(String mLogin) {
    this.mLogin = mLogin;
}
}

Here is the error what I am getting 这是我得到的错误

org.json.JSONException:  Value [{"url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/28","repository_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid","labels_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/28\/labels{\/name}","comments_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/28\/comments","events_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/28\/events","html_url":"https:\/\/github.com\/crashlytics\/secureudid\/pull\/28","id":222258999,"number":28,"title":"Fix broken headings in Markdown files","user":{"login":"bryant1410","id":3905501,"avatar_url":"https:\/\/avatars3.githubusercontent.com\/u\/3905501?v=4","gravatar_id":"","url":"https:\/\/api.github.com\/users\/bryant1410","html_url":"https:\/\/github.com\/bryant1410","followers_url":"https:\/\/api.github.com\/users\/bryant1410\/followers","following_url":"https:\/\/api.github.com\/users\/bryant1410\/following{\/other_user}","gists_url":"https:\/\/api.github.com\/users\/bryant1410\/gists{\/gist_id}","starred_url":"https:\/\/api.github.com\/users\/bryant1410\/starred{\/owner}{\/repo}","subscriptions_url":"https:\/\/api.github.com\/users\/bryant1410\/subscriptions","organizations_url":"https:\/\/api.github.com\/users\/bryant1410\/orgs","repos_url":"https:\/\/api.github.com\/users\/bryant1410\/repos","events_url":"https:\/\/api.github.com\/users\/bryant1410\/events{\/privacy}","received_events_url":"https:\/\/api.github.com\/users\/bryant1410\/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2017-04-17T23:26:47Z","updated_at":"2017-04-17T23:26:47Z","closed_at":null,"author_association":"NONE","pull_request":{"url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/pulls\/28","html_url":"https:\/\/github.com\/crashlytics\/secureudid\/pull\/28","diff_url":"https:\/\/github.com\/crashlytics\/secureudid\/pull\/28.diff","patch_url":"https:\/\/github.com\/crashlytics\/secureudid\/pull\/28.patch"},"body":"GitHub changed the way Markdown headings are parsed, so this change fixes it.\n\nSee [bryant1410\/readmesfix](https:\/\/github.com\/bryant1410\/readmesfix) for more information.\n\nTackles bryant1410\/readmesfix#1\n"},{"url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/13","repository_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid","labels_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/13\/labels{\/name}","comments_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/13\/comments","events_url":"https:\/\/api.github.com\/repos\/crashlytics\/secureudid\/issues\/13\/events","html_url":"https:\/\/github.com\/crashlytics\/secureudid\/issues\/13","id":3923240,"number":13,"title":"Not working with ARC","user":{"login":"SaschaMoellering","id":1321549,"avatar_url":"https:\/\/avatars0.githubusercontent.com\/u\/1321549?v=4","gravatar_id":"","url":"https:\/\/api.github.com\/users\/SaschaMoellering","html_url":"https:\/\/github.com\/SaschaMoellering","followers_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/followers","following_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/following{\/other_user}","gists_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/gists{\/gist_id}","starred_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/starred{\/owner}{\/repo}","subscriptions_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/subscriptions","organizations_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/orgs","repos_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/repos","events_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/events{\/privacy}","received_events_url":"https:\/\/api.github.com\/users\/SaschaMoellering\/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":10,"created_at":"20

You are trying to parse an array of object (from your webservices) to an object containing a property mResults which is an array of object ( Test ); 您正在尝试将对象数组(来自Web服务)解析为包含属性mResults的对象,该属性是对象数组( Test );

Instead of using Results class during parsing you need to directly use an ArrayList of Test : 代替在解析过程中使用Results类,您需要直接使用TestArrayList

Results results = gson.fromJson(response.toString(), Results.class);

should be 应该

ArrayList<Test> results = gson.fromJson(response.toString(), new TypeToken<ArrayList<Test>>(){}.getType());

As ArrayList is a generic it's not possible to use ArrayList<Test>.class to get a representation of the data type, we must use TypeToken . 由于ArrayList是泛型,因此无法使用 ArrayList<Test>.class来获取数据类型的表示形式,因此必须使用TypeToken What is TypeToken? 什么是TypeToken?

TypeToken represents a generic type T. Java doesn't yet provide a way to represent generic types, so this class does. TypeToken表示通用类型T。Java尚未提供表示通用类型的方法,因此此类可以。 Forces clients to create a subclass of this class which enables retrieval the type information even at runtime. 强制客户端创建此类的子类,即使在运行时也可以检索类型信息。

getType returns the type of the class used to build TypeToken and so we can use it in gson fromJson() parsing method. getType返回用于构建TypeToken的类的类型,因此我们可以在gson fromJson()解析方法中使用它。

-- -

Second problem: 第二个问题:

Your are using JsonObjectRequest but server response is a Json array so you need to use JsonArrayRequest and so update MyListner to use JSONArray instead of JSONObject . 您正在使用JsonObjectRequest但是服务器响应是一个Json数组,因此您需要使用JsonArrayRequest并更新MyListner以使用JSONArray而不是JSONObject

BUT

As your are parsing server response manually you can use StringRequest and so avoid parsing step of Volley . 当您手动解析服务器响应时,可以使用StringRequest ,因此避免了Volley解析步骤。

StringRequest jsonObjectRequest = new StringRequest(
    Request.Method.GET,
    "https://api.github.com/repos/crashlytics/secureudid/issues",
    new MyListner(),
    new MyErrorListner()
);

and MyListner is now directly using String : MyListner现在直接使用String

class MyListner implements Response.Listener<String> {
    @Override
    public void onResponse(String response) {
        Gson gson = new Gson();
        ArrayList<Test> results = gson.fromJson(response, new TypeToken<ArrayList<Test>>() {}.getType());

        for (Test t : results) {
            Log.e("Tag", t.toString());
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM