1

JSONやデータの解析などは初めてです。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>(); }
}

完全なソースを表示する必要がある場合は、ここで検索してください

現在の問題

  • NullPointerException
  • URL 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): com.jaisonbrooks.enlightenme.PullJSONData$SystemsRetrieverAsyncTask.onPostExecute(PullJSONData.java:96) 04-29 15:43:25.735: E/AndroidRuntime(3678): 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): java.lang.reflect.Method.invokeNative(ネイティブ メソッド) で04-29 15:43:25.735: E/AndroidRuntime(3678): 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): com.android.internal.os.ZygoteInit.main(ZygoteInit) で.java:773) 04-29 15:43:25.735: E/AndroidRuntime(3678): dalvik.system.NativeStart.main(ネイティブ メソッド) で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): java.lang.reflect.Method.invokeNative(ネイティブ メソッド) 04-29 15:43:25.735: E/AndroidRuntime(3678): java.lang.reflect.Method.invoke(Method. java:511) 04-29 15:43:25.735: E/AndroidRuntime(3678): com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006) 04-29 15:43:25.735: E/AndroidRuntime (3678): com.android.internal.os.ZygoteInit.main (ZygoteInit.java:773) 04-29 15:43:25.735: E/AndroidRuntime (3678): dalvik.system.NativeStart.main で(ネイティブメソッド)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): java.lang.reflect.Method.invokeNative(ネイティブ メソッド) 04-29 15:43:25.735: E/AndroidRuntime(3678): java.lang.reflect.Method.invoke(Method. java:511) 04-29 15:43:25.735: E/AndroidRuntime(3678): com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006) 04-29 15:43:25.735: E/AndroidRuntime (3678): com.android.internal.os.ZygoteInit.main (ZygoteInit.java:773) 04-29 15:43:25.735: E/AndroidRuntime (3678): dalvik.system.NativeStart.main で(ネイティブメソッド)E/AndroidRuntime(3678): java.lang.reflect.Method.invokeNative(ネイティブ メソッド) 04-29 15:43:25.735: E/AndroidRuntime(3678): java.lang.reflect.Method.invoke(Method. java:511) 04-29 15:43:25.735: E/AndroidRuntime(3678): com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006) 04-29 15:43:25.735: E/AndroidRuntime (3678): com.android.internal.os.ZygoteInit.main (ZygoteInit.java:773) 04-29 15:43:25.735: E/AndroidRuntime (3678): dalvik.system.NativeStart.main で(ネイティブメソッド)E/AndroidRuntime(3678): java.lang.reflect.Method.invokeNative(ネイティブ メソッド) 04-29 15:43:25.735: E/AndroidRuntime(3678): java.lang.reflect.Method.invoke(Method. java:511) 04-29 15:43:25.735: E/AndroidRuntime(3678): com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006) 04-29 15:43:25.735: E/AndroidRuntime (3678): com.android.internal.os.ZygoteInit.main (ZygoteInit.java:773) 04-29 15:43:25.735: E/AndroidRuntime (3678): dalvik.system.NativeStart.main で(ネイティブメソッド)E/AndroidRuntime (3678): com.android.internal.os.ZygoteInit.main (ZygoteInit.java:773) 04-29 15:43:25.735: E/AndroidRuntime (3678): dalvik.system.NativeStart.main で(ネイティブメソッド)E/AndroidRuntime (3678): com.android.internal.os.ZygoteInit.main (ZygoteInit.java:773) 04-29 15:43:25.735: E/AndroidRuntime (3678): dalvik.system.NativeStart.main で(ネイティブメソッド)

4

4 に答える 4

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 内の名前がデータ モデル内の名前に対応していることを確認することだけです。

他の gson 応答に再利用できるように、完全に汎用的な GsonSerializer も含めました。

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());

これで、ほぼプラグ アンド プレイできるようになります。いくつかの小さな調整が必要になる可能性があります。

于 2013-04-29T20:49:09.693 に答える
0

Jackconのようなライブラリを使用することをお勧めします: http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/

于 2013-04-29T19:40:55.813 に答える
0

JSON Serialization ライブラリをお勧めします。Google 独自の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で表します) 。

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
}
于 2013-04-29T21:18:54.580 に答える
0

あなたが得る応答は、内部に「systems」という名前のです。JSONObject {...}JOSNArray [...]

内の要素 (その他JSONObjectの )を解析する場合は、Android で配布されているorg.jsonパッケージでJSONArray提供されるクラスを使用するか、 GSONJacksonなどの別の JSON ライブラリを使用して実行できます。

最初に、最も外側の からデータを抽出する必要がありますJSONObject。そのためには、 に電話してmyJSONObject.getJSONArray("systems");ください。結果の値はタイプになりますJSONArray。各位置でlength()呼び出しを繰り返すことができます。getJSONObject(i)

これらJSONObjectの には、実際にローカルで使用するデータが含まれています。

の要素をメンバ変数として含むモデル クラスを作成し、オブジェクトのデータ値を含む を取得JSONObjectするコンストラクタを提供することをお勧めします。JSONObject

このコンストラクタ内から、次のように JSONObject の値を読み取ることができます。this.city = myJSONObject.getString("city");

手始めに、org.json パッケージを使用して、 JSON自体に慣れることができます。

于 2013-04-29T19:53:12.167 に答える