(32) Jacksonで JSONデータをデコードする。

投稿者: | 2023年1月15日

262 views

この記事は最終更新から 445日 が経過しています。

1. やりたいこと

Androidプログラム中で JSON形式のデータをデコードしたい。

2. やってみる

(1) Gradleに Jacksonパッケージを追加する。

最新版は以下のサイトで確認する。
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations

dependencies {
    implementation 'androidx.appcompat:appcompat:1.5.1'
    implementation 'com.google.android.material:material:1.7.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.14.1'
    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.14.1'
    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.14.1'
}

記述後は、Sync now メニューを選択し、パッケージのダウンロードを実行する。

(2) JSONデータを作る。

[
  {
    "textA": "山田",
    "textB": "神奈川",
    "textC": "自転車"
  },
  {
    "textA": "倉沢",
    "textB": "京都",
    "textC": "バイク"
  }
]

(3) JSONデコードのプログラムを書く。

デコード後のデータを格納するクラスを作る。

class Item {
    private String  textA;
    private String  textB;
    private String  textC;

    public String GetTextA(){return textA;}
    public String GetTextB(){return textB;}
    public String GetTextC(){return textC;}
}

データをデコードする処理を書く。

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

void DecodeJson(String jsonText) {
    // JSONデータをデコードする。
    ObjectMapper jsonMapper = new ObjectMapper().setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
                                                .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
    try {
        Item[] items = jsonMapper.readValue(jsonText, Item[].class);
        // デーコードした内容を表示してみる。
        for(Item i : items) {
            String msg = String.format("A: %s, B: %s, C: %s", i.GetTextA(), i.GetTextB(), i.GetTextC());
        }
    } catch (JsonParseException e1) {
        e1.printStackTrace();
    } catch (JsonMappingException e2) {
        e2.printStackTrace();
    } catch (JsonProcessingException e3) {
        e3.printStackTrace();
    }
}

3. 応用

(1) 少し汎用っぽい処理の備忘録

ObjectMapper.readTree()を使い JSONデータから JsonNode型インスタンスで構成される木構造を生成する。
 → ラベル名を指定して任意のノードを取得する。
  → そのノードのJSONデータを取得する。
   → ObjectMapper.readValue()でデコードする。

例として、以下のような JSONデータをデコードするケースについて…

{
  "result": "0",
  "data" : 
     [
       {"a":"11", "b":"23", "c":"35"},
       {"a":"43", "b":"38", "c":"61"},
       {"a":"15", "b":"72", "c":"29"}
     ]
}
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class RestDecoder {
    private JsonNode node;
    private int resultCode;
    ObjectMapper jsonMapper;

    // コンストラクタ
    public RestDecoder(){
        this.resultCode = -1;       // 非0(≠正常)で初期化
    }

    // サーバーから受信したデータ(JSON形式)をデコードする。
    public boolean execDecode(String jsonRawData) throws JsonParseException, JsonMappingException, JsonProcessingException {
        this.jsonMapper = new ObjectMapper().setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
                                            .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
        this.node = this.jsonMapper.readTree(jsonRawData);
        this.resultCode = this.node.get("result").asInt();
        return this.isRestResultDone();
    }

    // サーバーから受信したデータ中の「実行結果コード」を取得する。
    public boolean isRestResultDone() {
        return 0 == this.resultCode;
    }
    public boolean isRestResultLessInventory() {
        return RestResultCode.REST_RESULT_LESS_INVENBTORY == this.resultCode;
    }
    public boolean isRestResultLostItem() {
        return RestResultCode.REST_RESULT_LOST_ITEM == this.resultCode;
    }

    // サーバーから受信した商品情報(MyData型オブジェクト配列)を取得する。
    public MyData[] getDataAsItemData() throws JsonProcessingException {
        MyData[] myData = null;
        if(this.isRestResultDone()) {       // 正常にデータを受信済み?
            String jsonMyData = this.node.get("data").toString();
            myData = this.jsonMapper.readValue(jsonMyData, MyData[].class);
        }
        return myData;
    }

    // サーバーから受信したデータ中の「エラーメッセージ」を取得する。
    public String getRestMessage() {
        String msg = "";
        if(!this.isRestResultDone()){
            msg = this.node.get("message").toString();
        }
        return msg;
    }
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)