3

このチュートリアルをベースとして、Redmine APIによって生成された JSONを GSON で解析しようとしています。残念ながら、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;
}

完全な接線では、Javabean でプロパティを定義することをお勧めします (getter/setter を使用したプライベート変数とも呼ばれます)。

于 2013-02-20T21:55:22.727 に答える