在Android上解析JSON与GSON
问题描述:
我想用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;
}
答
您需要在您的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
使用[this json validator](http://jsonlint.com/)来验证你的json。它看起来很好。 – 2013-02-20 21:38:44
'列表 results = response.results'
Pete
2013-02-20 21:39:38
我查看了json的外观,并且该活动中列出的网址可以从外部访问。 – 2013-02-20 21:45:12