2013-02-20 78 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