3

我正在尝试使用本教程作为基础,使用 GSON解析由Redmine API生成的一些 JSON。不幸的是,我不能给你我的 JSON 的 URL,因为它只在内部工作,但它看起来像这样:

{
  "limit": 25,
  "total_count": 653,
  "offset": 0,
  "time_entries": [
    {
      "spent_on": "2013-02-14",
      "activity": {
        "name": "Blah1",
        "id": 10
      },
      "project": {
        "name": "TEST",
        "id": 10
      },
      "id": 661,
      "hours": 1,
      "updated_on": "2013-02-14T14:32:19Z",
      "user": {
        "name": "USER1",
        "id": 7
      },
      "issue": {
        "id": 467
      },
      "comments": "COMMENT 1",
      "created_on": "2013-02-14T14:32:19Z"
    },
    {
      "spent_on": "2013-02-14",
      "activity": {
        "name": "Bla2",
        "id": 10
      },
      "project": {
        "name": "TEST TEST",
        "id": 10
      },
      "id": 660,
      "hours": 1,
      "updated_on": "2013-02-14T11:52:13Z",
      "user": {
        "name": "USER2",
        "id": 4
      },
      "issue": {
        "id": 466
      },
      "comments": "COMMENT 2.",
      "created_on": "2013-02-14T11:52:13Z"
    }
  ]
}

我得到了一个NullPointerException,但我不确定是因为未能获取 JSON 还是建模错误。我担心我缺少与内部类有关的东西。如果它像错误地获取 JSON 一样简单,我会非常生气。

我的设备都是通过连接到内部网络的 WIFI 运行的,当我使用浏览器时可以看到 JSON,所以我认为这不是网络问题。

这是我的 LogCat:

02-20 21:11:11.175: E/AndroidRuntime(14450): FATAL EXCEPTION: main
02-20 21:11:11.175: E/AndroidRuntime(14450): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.javacodegeeks.android.json/com.javacodegeeks.android.json.JsonParsingActivity}: java.lang.NullPointerException
02-20 21:11:11.175: E/AndroidRuntime(14450):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
02-20 21:11:11.175: E/AndroidRuntime(14450):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
02-20 21:11:11.175: E/AndroidRuntime(14450):    at android.app.ActivityThread.access$600(ActivityThread.java:141)
02-20 21:11:11.175: E/AndroidRuntime(14450):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
02-20 21:11:11.175: E/AndroidRuntime(14450):    at android.os.Handler.dispatchMessage(Handler.java:99)
02-20 21:11:11.175: E/AndroidRuntime(14450):    at android.os.Looper.loop(Looper.java:137)
02-20 21:11:11.175: E/AndroidRuntime(14450):    at android.app.ActivityThread.main(ActivityThread.java:5041)
02-20 21:11:11.175: E/AndroidRuntime(14450):    at java.lang.reflect.Method.invokeNative(Native Method)
02-20 21:11:11.175: E/AndroidRuntime(14450):    at java.lang.reflect.Method.invoke(Method.java:511)
02-20 21:11:11.175: E/AndroidRuntime(14450):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-20 21:11:11.175: E/AndroidRuntime(14450):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-20 21:11:11.175: E/AndroidRuntime(14450):    at dalvik.system.NativeStart.main(Native Method)
02-20 21:11:11.175: E/AndroidRuntime(14450): Caused by: java.lang.NullPointerException
02-20 21:11:11.175: E/AndroidRuntime(14450):    at com.javacodegeeks.android.json.JsonParsingActivity.onCreate(JsonParsingActivity.java:46)
02-20 21:11:11.175: E/AndroidRuntime(14450):    at android.app.Activity.performCreate(Activity.java:5104)
02-20 21:11:11.175: E/AndroidRuntime(14450):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
02-20 21:11:11.175: E/AndroidRuntime(14450):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)

我的JsonParsingActivity

public class JsonParsingActivity extends Activity {

    String url = "URL";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        InputStream source = retrieveStream(url);
        Gson gson = new Gson();
        Reader reader = new InputStreamReader(source);
        RedmineResponse response = gson.fromJson(reader, RedmineResponse.class);

        Toast.makeText(this, response.query, Toast.LENGTH_SHORT).show();

        List<Result> results = response.results;
        for (Result result : results) {
            if (result.comments != null) {
                Toast.makeText(this, result.comments, Toast.LENGTH_SHORT).show();   
            } else {
                Toast.makeText(this, "EMPTY", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private InputStream retrieveStream(String url) {
        DefaultHttpClient client = new DefaultHttpClient();
        HttpGet getRequest = new HttpGet(url);

        try {
            HttpResponse getResponse = client.execute(getRequest);
            final int statusCode = getResponse.getStatusLine().getStatusCode();

            if (statusCode != HttpStatus.SC_OK) { 
                Log.w(getClass().getSimpleName(), "Error " + statusCode + " for URL " + url);
                return null;
            }

            HttpEntity getResponseEntity = getResponse.getEntity();
            return getResponseEntity.getContent();
        } catch (IOException e) {
            getRequest.abort();
            Log.w(getClass().getSimpleName(), "Error for URL " + url, e);
        }

        return null;
    }
}

我的Result班级:

public class Result {

    @SerializedName("id")
    public String time_entry_ID;

    @SerializedName("spent_on")
    public String spent_on;

    @SerializedName("created_on")
    public String created_on;

    public Project project;

    @SerializedName("hours")
    public String hours;

    @SerializedName("comments")
    public String comments;

    @SerializedName("iso_language_code")
    public String isoLanguageCode;

    @SerializedName("to_user_id_str")
    public String toUserIdStr;

    public String source;
}

我的RedmineResponse班级:

public class RedmineResponse {

    public List<Result> results;

    @SerializedName("limit")
    public int limit;

    @SerializedName("offset")
    public int offset;

    public String query;
}

我的Activity班级:

public class Activity {

    @SerializedName("id")
    public String activity_ID;

    @SerializedName("name")
    public String activity_name;
}

我的Issue班级:

public class Issue {

    @SerializedName("id")
    public String issue_ID;
}

我的Project班级:

public class Issue {

    @SerializedName("id")
    public String issue_ID;
}

我的User班级:

public class User {

    @SerializedName("id")
    public String user_ID;

    @SerializedName("name")
    public String user_name;
}
4

1 回答 1

3

您需要在映射中为results集合定义序列化属性名称:RedmineResponse

public class RedmineResponse {

    @SerializedName("time_entries") // This is the name you are using in JSON
    public List<Result> results;
}

在一个完整的切线上,最好在你的 Javabeans 上定义属性(也就是带有 getter/setter 的私有变量),因为这有助于更好地封装它们。

于 2013-02-20T21:55:22.727 回答