我是JSON和Parsing数据等的新手。我使用GSON并尝试拉出JSONArray“系统”,然后显示JSONObject的“system_name”然后显示它。 下面是要提取的JSON数据的示例。
{
"systems": [
{
"city": "Petaluma",
"country": "US",
"postal_code": "94954",
"state": "CA",
"status": "normal",
"system_id": 66,
"system_name": "Smith Residence",
"system_public_name": "Residential System",
"timezone": "America/Los_Angeles"
},
{
"city": "Atherton",
"country": "US",
"postal_code": "94954",
"state": "CA",
"status": "error",
"system_id": 77,
"system_name": "Jones Residence",
"system_public_name": "Jones Residence",
"timezone": "America/Los_Angeles"
}
]
}
API使用API_KEY进行身份验证,并像这样使用
https://api.company.com/api/systems?key=123ABC
public class PullJSONData extends Activity {
TextView systemsTextView;
ProgressDialog progressDialog;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
systemsTextView = (TextView) findViewById(R.id.textView);
this.retrieveSystems();
}
void retrieveSystems() {
progressDialog = ProgressDialog.show(this, "Please wait...",
"Retrieving data...", true, true);
SystemsRetrieverAsyncTask task = new SystemsRetrieverAsyncTask();
task.execute();
progressDialog.setOnCancelListener(new CancelListener(task));
}
private class SystemsRetrieverAsyncTask extends AsyncTask<Void, Void, Void> {
Response response;
@Override
protected Void doInBackground(Void... params) {
String url = "https://api.company.com/api";
HttpGet getRequest = new HttpGet(url);
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse getResponse = httpClient.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();
InputStream httpResponseStream = getResponseEntity.getContent();
Reader inputStreamReader = new InputStreamReader(
httpResponseStream);
Gson gson = new Gson();
SystemList systemList = gson.fromJson(jsonString, SystemList.class);
for (int i = 0; i < systemList.systems.size(); i++)
{
System s = systemList.systems.get(i);
}
this.response = gson
.fromJson(inputStreamReader, Response.class);
} catch (IOException e) {
getRequest.abort();
Log.w(getClass().getSimpleName(), "Error for URL " + url, e);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
StringBuilder builder = new StringBuilder();
for (System systems : this.response.data) {
builder.append(String.format(
"<br>System: <b>%s</b><br>City: <b>%s</b><br><br>",
systems.getCountry(), systems.getCity()));
}
systemsTextView.setText(Html.fromHtml(builder.toString()));
progressDialog.cancel();
}
}
private class CancelListener implements OnCancelListener {
AsyncTask<?, ?, ?> cancellableTask;
public CancelListener(AsyncTask<?, ?, ?> task) {
cancellableTask = task;
}
@Override
public void onCancel(DialogInterface dialog) {
cancellableTask.cancel(true);
}
}
public class Response {
ArrayList<System> data;
public Response() {
data = new ArrayList<System>();
}
public class System {
String city;
String country;
public System() {
this.city = "";
this.country = "";
}
public String getCity() {
return this.city;
}
public String getCountry() {
return this.country;
}
public class SystemList {
public List<System> systems;
public SystemList() { systems = new ArrayList<System>(); }
}
如果您需要查看完整来源,请查找IT HERE
来自网址https://api.company.com/api/systems/的错误401
04-29 15:43:25.735:E / AndroidRuntime(3678):致命异常:主要 04-29 15:43:25.735:E / AndroidRuntime(3678):java.lang.NullPointerException 04-29 15:43:25.735:E / AndroidRuntime(3678):at com.jaisonbrooks.enlightenme.PullJSONData $ SystemsRetrieverAsyncTask.onPostExecute(PullJSONData.java:96) 04-29 15:43:25.735:E / AndroidRuntime(3678):at com.jaisonbrooks.enlightenme.PullJSONData $ SystemsRetrieverAsyncTask.onPostExecute(PullJSONData.java:1) 04-29 15:43:25.735:E / AndroidRuntime(3678):在android.os.AsyncTask.finish(AsyncTask.java:631) 04-29 15:43:25.735:E / AndroidRuntime(3678):在android.os.AsyncTask.access $ 600(AsyncTask.java:177) 04-29 15:43:25.735:E / AndroidRuntime(3678):在android.os.AsyncTask $ InternalHandler.handleMessage(AsyncTask.java:644) 04-29 15:43:25.735:E / AndroidRuntime(3678):在android.os.Handler.dispatchMessage(Handler.java:99) 04-29 15:43:25.735:E / AndroidRuntime(3678):在android.os.Looper.loop(Looper.java:137) 04-29 15:43:25.735:E / AndroidRuntime(3678):在android.app.ActivityThread.main(ActivityThread.java:4898) 04-29 15:43:25.735:E / AndroidRuntime(3678):at java.lang.reflect.Method.invokeNative(Native Method) 04-29 15:43:25.735:E / AndroidRuntime(3678):at java.lang.reflect.Method.invoke(Method.java:511) 04-29 15:43:25.735:E / AndroidRuntime(3678):at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1006) 04-29 15:43:25.735:E / AndroidRuntime(3678):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773) 04-29 15:43:25.735:E / AndroidRuntime(3678):at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:1)
另一个选项(类似于上面的jackson)是使用Gson库。使用json处理是一项出色的工作。此外,它还有很好的记录和理解。
编辑:
好的,看看你的代码后,你似乎已经过度复杂了System和SystemList类。
public class System {
public String city;
public String country;
public String postal_code;
public String state;
public String status;
public String system_id;
public String system_name;
public String system_public_name;
public String timezone;
}
public class SystemsList {
public List<System> systems;
}
您需要做的就是确保json中的名称映射到数据模型中的名称。
我还添加了一个完全通用的GsonSerializer,以便可以将其重用于其他gson响应
public class GsonSerializer
{
private static final String TAG = "GsonSerializer";
public static <T> Object seralizeData (String response, T t)
{
Gson serializer = new Gson();
try
{
return serializer.fromJson(response, t.getClass());
}
catch (Exception e)
{
e.printStackTrace();
Logger.e(TAG, "deserialization failure: ".concat(response));
}
return null;
}
}
您使用此类的方式如下。
// Where mData is a class of type T
mData = (T) GsonSerializer.seralizeData(Json, mData);
// or in a specific example
mSystemList = (SystemList) GsonSerializer.seralizeData(Json, new SystemList());
这应该足以让你可以即插即用。可能需要进行一些小的调整。
答案 1 :(得分:0)
答案 2 :(得分:0)
您获得的回复是JSONObject
{...}
,其中JOSNArray
[...]
名为“系统”。
如果要解析JSONObject
中的元素(更多JSONArray
s),可以使用与Android一起分发的org.json包提供的类或使用另一个JSON库,如GSON或Jackson。
首先,您必须从最外层的JSONObject
中提取数据。为此,请致电myJSONObject.getJSONArray("systems");
。结果值的类型为JSONArray
。您可以在每个位置迭代length()
来getJSONObject(i)
。
这些JSONObject
包含您实际想要在本地使用的数据。
最好创建一个包含JSONObject
元素作为成员变量的模型类,并提供一个构造函数,它使JSONObject
包含对象数据值。
然后,您可以在此构造函数中读取JSONObject的值,如下所示:this.city = myJSONObject.getString("city");
对于初学者,你可以使用org.json包并熟悉JSON本身。
答案 3 :(得分:0)
我建议使用JSON序列化库。谷歌自己的GSON是我找到的最好的。对于您的数据,您可以执行以下操作:
创建一个与系统匹配的模型(我使用getter和setter,有些只使用公共字段,每个都使用公共字段):
public class System
{
private String city;
public String getCity { return city; }
public void setCity(string c) { city = c; }
private String country;
public String getCountry{ return country; }
public void setCountry(string c) { country = c; }
// .. the rest of the fields here
}
public class SystemList
{
public List<System> systems;
public SystemList() { systems = new List<System>(); }
}
然后要序列化您的顶级对象,请执行以下操作(注意,您的JSON包含在大括号{}中,这意味着顶级未命名对象。我们将用 SystemList )表示< / p>
Gson gson = new Gson();
SystemList systemList = gson.fromJson(jsonString, SystemList.class);
for (int i = 0; i < systemList.systems.size(); i++)
{
System s = systemList.systems.get(i);
// do something with system
}