2013-02-20 81 views
3

我想用GSON解析一下Redmine API生成的JSON,使用this tutorial作爲基礎。不幸的是,我不能給你的網址爲我的JSON,因爲它只能在內部,但它看起來是這樣的:在Android上解析JSON與GSON

{ 
    "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; 
} 
+1

使用[this json validator](http://jsonlint.com/)來驗證你的json。它看起來很好。 – 2013-02-20 21:38:44

+2

'列表 results = response.results' <---您確定結果不爲空嗎?這就是我認爲你有問題的地方。 – Pete 2013-02-20 21:39:38

+0

我查看了json的外觀,並且該活動中列出的網址可以從外部訪問。 – 2013-02-20 21:45:12

回答

3

您需要在您的RedmineResponse映射爲results集合定義序列化的屬性名稱:

public class RedmineResponse { 

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

在一個完整的切線,它能夠更好地對你的Javabean(帶的getter/setter方法又稱爲私有變量定義屬性),因爲這有助於更好地封裝它們。

+0

謝謝!這解決了它。我會考慮改變我的屬性,再次感謝! – ThrowingSpoon 2013-02-20 22:02:08