본문 바로가기
반응형
Programming/Android

안드로이드(Android) JSON을 객체 배열로 변환하기

by JAMINS 2020. 6. 14.

초기 DB를 구축하기 위해 각 라인당 json 텍스트가 있는 하나의 파일을 파싱하여 array object 형태로 변환하고자 한다. 이 때 Gson 라이브러리를 활용하여 사용해보자. 로또 데이터를 대상으로 변환해볼 것이다.

1. GSON 라이브러리 추가

Gson을 활용하기 전에 dependency를 추가해야한다. 아래와 같이 build.gradle에 추가한다.

dependencies {
  implementation 'com.google.code.gson:gson:2.8.6'
}

2. JSON 준비

변환할 json 파일을 준비한다. 이미 크롤링을 한 json파일을 Asset 폴더에 저장해둔다. Asset폴더가 없다면 new -> Folder -> Asset 으로 생성할 수 있다. 아래와 같이 lotto_official.json 파일을 위치시킨다.

JSON 형태

[
  {...},
  {...},
  ...
]

형태는 Object가 배열 형태로 붙어있다. lotto_official.json 의 내용을 보면 대략 다음과 같다.

[
  {
    "totSellamnt": 3681782000,
    "returnValue": "success",
    "drwNoDate": "2002-12-07",
    "firstWinamnt": 0,
    "drwtNo6": 40,
    "drwtNo4": 33,
    "firstPrzwnerCo": 0,
    "drwtNo5": 37,
    "bnusNo": 16,
    "firstAccumamnt": 863604600,
    "drwNo": 1,
    "drwtNo2": 23,
    "drwtNo3": 29,
    "drwtNo1": 10
  },
  {
    "totSellamnt": 4904274000,
    "returnValue": "success",
    "drwNoDate": "2002-12-14",
    "firstWinamnt": 2002006800,
    "drwtNo6": 42,
    "drwtNo4": 25,
    "firstPrzwnerCo": 1,
    "drwtNo5": 32,
    "bnusNo": 2,
    "firstAccumamnt": 0,
    "drwNo": 2,
    "drwtNo2": 13,
    "drwtNo3": 21,
    "drwtNo1": 9
  },
  {
    "totSellamnt": 4729342000,
    "returnValue": "success",
    "drwNoDate": "2002-12-21",
    "firstWinamnt": 2000000000,
    "drwtNo6": 31,
    "drwtNo4": 21,
    "firstPrzwnerCo": 1,
    "drwtNo5": 27,
    "bnusNo": 30,
    "firstAccumamnt": 0,
    "drwNo": 3,
    "drwtNo2": 16,
    "drwtNo3": 19,
    "drwtNo1": 11
  },
  ...
]

이를 List<T> 형태로 변환하여 DB화 하는 것이 목적이다.

 

 

3. 변환

변환하기 전 Entity 클래스를 정의해야한다. 각 Object당 매핑될 클래스이다. 일반 클래스 형태로 정의해도 되지만, Room 라이브러리와 함께 사용할 것이므로 Entity로 생성했다.

@Entity(tableName = "lotto_official")
public class LottoOfficial {
    @PrimaryKey
    @ColumnInfo(name = "drw_no")
    public int drwNo;

    @ColumnInfo(name = "drw_no_date")
    public String drwNoDate;

    @ColumnInfo(name = "drwt_no_1")
    public int drwtNo1;

    @ColumnInfo(name = "drwt_no_2")
    public int drwtNo2;

    @ColumnInfo(name = "drwt_no_3")
    public int drwtNo3;

    @ColumnInfo(name = "drwt_no_4")
    public int drwtNo4;

    @ColumnInfo(name = "drwt_no_5")
    public int drwtNo5;

    @ColumnInfo(name = "drwt_no_6")
    public int drwtNo6;

    @ColumnInfo(name = "bnus_no")
    public int bnusNo;

    @ColumnInfo(name = "first_accum_amnt")
    public long firstAccumamnt;

    @ColumnInfo(name = "first_prz_wner_co")
    public int firstPrzwnerCo;

    @ColumnInfo(name = "first_win_amnt")
    public long firstWinamnt;

    @ColumnInfo(name = "tot_sell_amnt")
    public long totSellamnt;

    public LottoOfficial(int drwNo, String drwNoDate, int drwtNo1, int drwtNo2, int drwtNo3, int drwtNo4, int drwtNo5, int drwtNo6, int bnusNo, long firstAccumamnt, int firstPrzwnerCo, long firstWinamnt, long totSellamnt) {
        this.drwNo = drwNo;
        this.drwNoDate = drwNoDate;
        this.drwtNo1 = drwtNo1;
        this.drwtNo2 = drwtNo2;
        this.drwtNo3 = drwtNo3;
        this.drwtNo4 = drwtNo4;
        this.drwtNo5 = drwtNo5;
        this.drwtNo6 = drwtNo6;
        this.bnusNo = bnusNo;
        this.firstAccumamnt = firstAccumamnt;
        this.firstPrzwnerCo = firstPrzwnerCo;
        this.firstWinamnt = firstWinamnt;
        this.totSellamnt = totSellamnt;
    }

    // getter, setter
}

JSON 값의 형태에 맞게 Type을 지정하고 변수명도 일치하도록 한다. 그 다음Assetlotto_official.json 을 InputStream으로 가져온 후 아래와 같이 Gson 라이브러리로 변환할 수 있다.

InputStream is = context.getAssets().open("lotto_official.json");
JsonReader reader = new JsonReader(new InputStreamReader(is));

Type type = new TypeToken<List<LottoOfficial>>() {}.getType();
List<LottoOfficial> list = new Gson().fromJson(reader, type);

적용한 전체 코드의 형태는 아래와 같다.

try (
  InputStream is = context.getAssets().open("lotto_official.json");
  JsonReader reader = new JsonReader(new InputStreamReader(is))
) {
  Type type = new TypeToken<List<LottoOfficial>>() {}.getType();
  List<LottoOfficial> list = new Gson().fromJson(reader, type);

  // Room DB bulk insert
  instance.runInTransaction(() -> {
    instance.lottoDao().bulkInsert(list);
  });
} catch (IOException e) {
  e.printStackTrace();
}

4. 초기 DB 생성할 때 적용

안드로이드 앱 최초 설치시 로컬 데이터베이스는 텅 비어있는 상태이다. 준비한 데이터를 밀어넣는 작업이 필요하며 한 번 구축이 된 이후 사용자가 앱을 지우지 않는 이상 유지, 관리만 하면 된다. lotto_official.json 파일은 초기 DB 구축용으로 생성해둔 데이터이기 때문에 적용해야한다. 이 때 Room 라이브러리를 활용했다.

AppDatabase sInstance = Room
  .databaseBuilder(context, AppDatabase.class, "lotto-db")
  .addCallback(new Callback() {
    @Override
    public void onCreate(@NonNull SupportSQLiteDatabase db) {
      super.onCreate(db);

      executor.getDbExecutor().execute(() -> {
        AppDatabase instance = AppDatabase.getInstance(context, executor);

        // JSON 변환 후 BulkInsert하는 기능
        DataGenerator.bulkInsertInitData(context, instance);
      });
    }
  })
  .build();

@Database 생성 시 addCallback을 이용하여 최초 밀어넣는 기능을 구현할 수 있다. 위와 같이 별도의 클래스로 분리하여 수행하도록 하였다. 이상 JSON 데이터를 객체 배열의 형태로 변환하고 Android DB로 밀어넣는 것 까지 알아보았다. Room을 활용한 DB다루는 내용은 추후에 다루도록 하겠다.

댓글