JSONウェブサービスを実行
Consuming JSON Web Services
XMLウェブサービスは別として、
他のウェブサービスのタイプとして、JSON、
(JavaScript Object Notation)が一般的になってきています。
JSONは人間とコンピュータで処理させやすいように設計された
データを強調する交換フォーマットです。
XMLドキュメントではデータの意味を表現するためにタグを使いますが、
JSONでは波カッコ”{”、”}”、コロン”,”、角カッコ”[”、"]"を
名前/値のペアや配列でデータを編成します。
ここでは、開発するAndroidアプリケーションで
JSONウェブサービスをどのように消費するかを示します。
これから2つのJSONウェブサービスを使っていきます。
●GeoNames JSONウェブサービス
ロケーションが与えられているかどうかを返すサービスを提供します。
JSON文字列として結果が返されます。
●GeoNames 郵便番号検索
検索で与えられた郵便番号と一致している市町村のリストを
返すサービスを提供します。
ちょっと注釈
この例はサードパーティのウェブサービスが動くプロパティに
依ります。この例では、geoname.orgのポリシーを使い
アクセスできる元で、デモアカウントを使います。
すべてのアカウントと同じように、デモアカウントはそれぞれの
24時間ごとにどのくらい検索語がサービスされているか制限されています。
もしここにあるコードを試したときに説明のないエラーを受け取ったと
したら、デモアカウントは制限いっぱいに達したと考えられます。
開発者自身のデモアカウントのサイトで登録していれば、
この問題を回避できます。
登録や追加の情報はhttp://www.geoname.org/loginで入手可能です。
ウェブサービスに接続し、帰ってくるJSON文字列を取得するためには、
単純にHTTP GETかPOSTを使ってサーバに接続します。
(より簡単にするために、この例ではHTTP GETを使っています。
HTTP GETのことはHTTP GETでサーバに接続するを
見てください。)
そしてその時JSONフォーマットで返ってくる文字列を取得します。
JSONオブジェクトを取得するためのreadJSONFeed()メソッドは
以下の様になります。
public String readJSONFeed(String URL){
StringBuilder stringBuilder = new StringBuilder();
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(URL);
try{
HttpResponse response = httpClient.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200){
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null){
stringBuilder.append(line);
}
inputStream.close();
}else{
Log.d("readJSONFeed", "Failed to download file");
}
}catch (Exception e){
Log.d("readJSONFeed", e.getLocalizedMessage());
}
return stringBuilder.toString();
}
JSONウェブサービスを実行することで最適な残りの課題は、
返って来たJSON文字列を構文解析していることです。
最初に使っていくサービスで対となる緯度、経度の値を渡し、
位置に関する情報かどうかを返します。
例えば以下のような結果が返って来ます。
{
"weatherObservation":{
"clouds": "scattered clouds",
"weatherCondition": "n/a",
"observation":"KCFV 09852Z AUTO 06005KT 10SM
SCT030 SCT110 24/20 A3000 RMK A02 SLO148 T02390200 53002",
windDirection":60,
ICAO":"KCFV",
"seaLevelPressure":1014.8,
"elevation":225,
"lng":-95.56666666666666,
"temperature":"23.9",
"dewPoint":"20",
"windSped":"05",
"humidity":78,
"stationName":"Coffeyville, Coffeyville Municipal Airport",
"datetime":"2012-07-09-08:52:00",
lat":37.08333333333336
}
}
ウェブサービスに接続しJSONの結果を構文解析するために、
以下のようなクラスを作ることができます。
private class ReadWeatherJSONFeedTask extends AsyncTask<String, Void, String>{
protected String doInVackground{
return readJSONFeed(urls[0]);
}
protected void onPostExecute(String result){
try{
JSONObject jsonObject = new JSONObject(result);
JSONObject weatherObservationItems =new JSONObject(
jsonObject.getString("weatherObservation"));
Toast.makkeText(getBaseContext(),
weatherObservationItems.getString("clouds") +
" - " + weatherObservationItems.getString("stationName"),
Toast.LENGTH_LONG).show();
}catch(Exception e){
Log.d("ReadWeatherJSONFeedTask", e.getLocalizedMessage());
}
}
}
以下のようなことに注目することが重要です。
●キー/値の地図作成でJSONオブジェクトの中で
JSON文字列を変換するためのJSONObjectクラスを使うこと。
●JSONObjectクラスのgetString()メソッドは、
キーで指定された値を返します。この例では、
weatherObservationキーの値を返しています。
この返ってくる結果はその時にJSONオブジェクトに変換されます。
●JSONオブジェクト内部のそれぞれ個々のキーの値を検索できます。
上の例での、clouds、stationNameなどのように。
ReadWeatherJSONFeedTaskクラスを使うためには、
以下のようなステートメントを使います。
new ReadWeatherJSONFeedTask().execute{
"http://ws.geonames.org/findNearByWeatherJSON?lat=" +
txtLat.getEditableText().toString() + "&lng=" +
txtLong.getText().toString());
他の例を見ていきます。
2番目のウェブサービスは郵便番号で指定された市町村リストを返します。
ウェブサービスからの結果は次の様になります。
{
"postlCodes": [
{
"adminCode3":"3203",
"adminName2":"Wahlkreis St.Gallen",
"adminName3":St.Gallen",
"adminName2":"1721",
"adminName1":"SG",
"postalCode":"9011",
"countryCode":"CH",
"lng":9.399858534040646,
"placeName":"St. Gallen",
"lat":47.414775328611945,
"adminName1":"Kanton St. Gallen"
},
{
"adminCode1":"GS",
"postalCode":"9011",
"countryCode":"HU",
"lng":17.781944437499998,
"placeName":"Gyor",
"lat":47.607638900000005,
adminName1":"Gyor-Moson-Sopron"
},
{
"adminName2":"TromsΘ",
"adminCode2":"1902",
"adminCode1":"19",
"postalCode":"9011",
"countryCode":"NO",
"lng":18.95508,
"placeName":"Troms",
"lat":69.6489,
#adminName1":"Troms"
},
{
.........
}
}
}
ウェブサービスを使うためには、以下のようなクラスを作ることができます。
private class ReadPlacesFeedTask extends AsyncTask<String, Void, String>{
protected String doInBackground(Stringd... this){
return readJSONFeed(urls[0]);
}
protexted void onPostExecute(String result){
try{
JSONObject jsonObject = new JSONObject(result);
JSONArray postalCodesItems = new
JSONArray(jsonObject.getString("postalCodes"));
//---print out the content of the json feed---
for (int i = 0; i < postalCodesItems.length(); i++){
JSONObject postalCodesItem =
postalCodesItems.getJSONObject(i);
Toast.makeText(getBaseContext(),
postalCodesItem.getString("postalCode") + " - " +
postalCodesItem.getString("placeName") + ", " +
postlCodesItem.getString("countryCode"),
Toast.LENGTH_SHORT).show();
}
} catch(Exception e){
Log.d("ReadPlacesFeedTask", e.getLocalizedMessage());
}
}
}
上のコードでは以下のような所に注目するのが重要です。
●キー/値の地図作成でJSONオブジェクトの中に
JSON文字列を変換するためにJSONObjectクラスを使います。
●JSONObjectクラスのgetString()メソッドは
キーで指定された値を返します。この例では、
このメソッドはpostalCodesキーの値を返してます。
返ってくる結果はその時にJSONArrayオブジェクトに変換され、
変換されたものはJSONオブジェクトの配列に格納されます。
●JSONArray中を繰り返し、個々のキーの値を
それぞれのJSONオブジェクトが引き出します。
postalCode、placeName、countryCodeなどがそうです。
ReadPlacesFeedTaskクラスを使うために、
以下のようなステートメントを使います。
new ReadPlacesFeedTask().execute{
"http://api.geonames.org/postalCodeSearchJSON?postalcode=" +
txtPostalCode.getEditableText().toString() +
"&maxRows=10&username=demo");
|
【用語解説】
XML
HTMLと同じような言語ですが、
すべての型の複雑なデータ構造を
送信するための設計ができる
ファイル型式。
オブジェクト
ある手続きを持った
データアイテムで、
他の手続きと関連づけされるもの
metaタグ
ウェブページに与える
情報の宣言につかわれ
検索エンジン・ウェブアプリ
などにウェブページの内容を
伝える役目をする。
metaタグの内容は
ページ内に表示されない。
コンストラクタ
オブジェクト指向
プログラミングで使われ
新しいオブジェクトが
作られ時に呼び出される
メソッドのこと。
クラス
オブジェクト指向
プログラミングでの
オブジェクトの型
オブジェクト指向プログラミング
プログラミングの
方式のことで、
プログラマはデータ型を
定義できるだけでなく
自動的にデータ型と
メソッドを関連付け
できる
アクティビティ
Androidにおける
アクティビティは
Androidアプリの画面に
相当するもの
ボタンやウェブページ
など表示されている
すべてのもののこと。
view
Androidのアプリを開発する
上で使う部品のことで、
トリガボタン・イメージボタン
チェックボックスなどのこと。
UI
ユーザインターフェースのこと。
Bind(バインド)
シンボルとデータを
関連させるため
または、データの一片と
他のものを関連させること。
以下は例。
・変数に値を入れる。
(変数の初期化)
・特定のEthernetポートと
ネットワークプロトコルを
関連付けする。
・Javaの変数のセット上に
XML文書を配置すること。
または、ほかの
プログラミング言語でも。
|