Android

[Android/kotlin] okhttp & retrofit으로 json 파싱하기

dev_zoe 2021. 1. 29. 03:12
반응형

OkHttp란?

http를 더 간편하고 효율적으로 쓸 수 있도록 돕는 라이브러리

Retrofit이란?

안드로이드 앱에서 restful 통신을 할 수 있도록 도와주는 라이브러리

※ restful 이란? devyul.tistory.com/entry/Network-REST-Restful-REST-API-%EC%A0%95%EB%A6%AC 참조

 

영화 진흥 위원회 API의 JSON 파싱하기

- Retrofit 사용

 

1. gradle 설정

dependencies {
    ...
    // Retrofit2
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    // Json Parser
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    ...
}

 

2. AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
//application 태그 안에
android:usesCleartextTraffic="true"

 

3. 영화진흥위원회 가입 후 API Key 발급받기

www.kobis.or.kr/kobisopenapi/homepg/apiservice/searchServiceInfo.do

 

영화진흥위원회 오픈API

제공서비스 영화관입장권통합전산망이 제공하는 오픈API서비스 모음입니다. 사용 가능한 서비스를 확인하고 서비스별 인터페이스 정보를 조회합니다.

www.kobis.or.kr

4. Pojo 클래스 생성

 

json 데이터를 받아올 껍데기 클래스인 Pojo 클래스를 생성해야한다.

www.jsonschema2pojo.org/

 

위 사이트에서 영화진흥위원회 open api로 받아온 json 코드를 복사 붙여넣기 후,

(일별 박스 오피스일 경우 ->

http://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key={apikey}&targetDt={yyyymmdd}  

 

{apikey}에는 회원가입 후 발급받은 key, {yyyymmdd} 에는 20120101 과 같은 형식의 일별 박스오피스 데이터를 얻고자 하는 날짜를 입력한다.)

 

하단의 Preview버튼을 누르면 Pojo 클래스가 생성된다.

 

BoxOfficeResult.java

package leeyuri.mobile.retrofittest;

import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class BoxOfficeResult {

    @SerializedName("boxofficeType")
    @Expose
    private String boxofficeType;
    @SerializedName("showRange")
    @Expose
    private String showRange;
    @SerializedName("dailyBoxOfficeList")
    @Expose
    private List<DailyBoxOfficeList> dailyBoxOfficeList = null;

    public String getBoxofficeType() {
        return boxofficeType;
    }

    public void setBoxofficeType(String boxofficeType) {
        this.boxofficeType = boxofficeType;
    }

    public String getShowRange() {
        return showRange;
    }

    public void setShowRange(String showRange) {
        this.showRange = showRange;
    }

    public List<DailyBoxOfficeList> getDailyBoxOfficeList() {
        return dailyBoxOfficeList;
    }

    public void setDailyBoxOfficeList(List<DailyBoxOfficeList> dailyBoxOfficeList) {
        this.dailyBoxOfficeList = dailyBoxOfficeList;
    }
}

 

DailyBoxOfficeList.java

package leeyuri.mobile.retrofittest;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class DailyBoxOfficeList {

    @SerializedName("rnum")
    @Expose
    private String rnum;
    @SerializedName("rank")
    @Expose
    private String rank;
    @SerializedName("rankInten")
    @Expose
    private String rankInten;
    @SerializedName("rankOldAndNew")
    @Expose
    private String rankOldAndNew;
    @SerializedName("movieCd")
    @Expose
    private String movieCd;
    @SerializedName("movieNm")
    @Expose
    private String movieNm;
    @SerializedName("openDt")
    @Expose
    private String openDt;
    @SerializedName("salesAmt")
    @Expose
    private String salesAmt;
    @SerializedName("salesShare")
    @Expose
    private String salesShare;
    @SerializedName("salesInten")
    @Expose
    private String salesInten;
    @SerializedName("salesChange")
    @Expose
    private String salesChange;
    @SerializedName("salesAcc")
    @Expose
    private String salesAcc;
    @SerializedName("audiCnt")
    @Expose
    private String audiCnt;
    @SerializedName("audiInten")
    @Expose
    private String audiInten;
    @SerializedName("audiChange")
    @Expose
    private String audiChange;
    @SerializedName("audiAcc")
    @Expose
    private String audiAcc;
    @SerializedName("scrnCnt")
    @Expose
    private String scrnCnt;
    @SerializedName("showCnt")
    @Expose
    private String showCnt;

    public String getRnum() {
        return rnum;
    }

    public void setRnum(String rnum) {
        this.rnum = rnum;
    }

    public String getRank() {
        return rank;
    }

    public void setRank(String rank) {
        this.rank = rank;
    }

    public String getRankInten() {
        return rankInten;
    }

    public void setRankInten(String rankInten) {
        this.rankInten = rankInten;
    }

    public String getRankOldAndNew() {
        return rankOldAndNew;
    }

    public void setRankOldAndNew(String rankOldAndNew) {
        this.rankOldAndNew = rankOldAndNew;
    }

    public String getMovieCd() {
        return movieCd;
    }

    public void setMovieCd(String movieCd) {
        this.movieCd = movieCd;
    }

    public String getMovieNm() {
        return movieNm;
    }

    public void setMovieNm(String movieNm) {
        this.movieNm = movieNm;
    }

    public String getOpenDt() {
        return openDt;
    }

    public void setOpenDt(String openDt) {
        this.openDt = openDt;
    }

    public String getSalesAmt() {
        return salesAmt;
    }

    public void setSalesAmt(String salesAmt) {
        this.salesAmt = salesAmt;
    }

    public String getSalesShare() {
        return salesShare;
    }

    public void setSalesShare(String salesShare) {
        this.salesShare = salesShare;
    }

    public String getSalesInten() {
        return salesInten;
    }

    public void setSalesInten(String salesInten) {
        this.salesInten = salesInten;
    }

    public String getSalesChange() {
        return salesChange;
    }

    public void setSalesChange(String salesChange) {
        this.salesChange = salesChange;
    }

    public String getSalesAcc() {
        return salesAcc;
    }

    public void setSalesAcc(String salesAcc) {
        this.salesAcc = salesAcc;
    }

    public String getAudiCnt() {
        return audiCnt;
    }

    public void setAudiCnt(String audiCnt) {
        this.audiCnt = audiCnt;
    }

    public String getAudiInten() {
        return audiInten;
    }

    public void setAudiInten(String audiInten) {
        this.audiInten = audiInten;
    }

    public String getAudiChange() {
        return audiChange;
    }

    public void setAudiChange(String audiChange) {
        this.audiChange = audiChange;
    }

    public String getAudiAcc() {
        return audiAcc;
    }

    public void setAudiAcc(String audiAcc) {
        this.audiAcc = audiAcc;
    }

    public String getScrnCnt() {
        return scrnCnt;
    }

    public void setScrnCnt(String scrnCnt) {
        this.scrnCnt = scrnCnt;
    }

    public String getShowCnt() {
        return showCnt;
    }

    public void setShowCnt(String showCnt) {
        this.showCnt = showCnt;
    }

}

 

Result.java - 전체 결과

package leeyuri.mobile.retrofittest;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Result {

    @SerializedName("boxOfficeResult")
    @Expose
    private BoxOfficeResult boxOfficeResult;

    public BoxOfficeResult getBoxOfficeResult() {
        return boxOfficeResult;
    }

    public void setBoxOfficeResult(BoxOfficeResult boxOfficeResult) {
        this.boxOfficeResult = boxOfficeResult;
    }
}

위 코드에서

 

@SerialzedName : JSON에서 데이터에 매칭되는 이름 명시

@Expose : 해당값이 null일경우 json으로 만들 필드를 자동 생략

 

5. retrofit 통신 인터페이스와 retrofit client 작성

 

RetrofitInterface.java

package leeyuri.mobile.retrofittest;

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;

public interface RetrofitInterface {

    //get : 정보조회
    @GET("http://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json")
    Call<Result> getBoxOffice(@Query("key") String key, @Query("targetDt") String targetDt);
}
  • annotation : get/post/delete/put 중 하려는 작업에 맞게 하나를 선택하며 작업을 수행할 주소를 괄호 안에 적는다.
  • Call<데이터 객체 타입> @Query("요청 매개변수") 변수

 

RetrofitClient.java

package leeyuri.mobile.retrofittest;

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitClient {
    private static RetrofitClient instance = null;
    private static RetrofitInterface retrofitInterface;
    private static String baseUrl = "http://www.kobis.or.kr";

    private RetrofitClient() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        retrofitInterface = retrofit.create(RetrofitInterface.class);
    }

    public static RetrofitClient getInstance() {
        if (instance == null) {
            instance = new RetrofitClient();
        }
        return instance;
    }

    public static RetrofitInterface getRetrofitInterface() {
        return retrofitInterface;
    }
}

 

  • baseUrl(오픈 api의 서버 url)
  • addConverterFactory(데이터 파싱 설정) : 예시에서는 json을 gson으로 parsing할 것이기 때문에 GsonConverterFactory.create()로 gsonconverter를 얻어온다.
  • build() : Retrofit 객체 생성

6. MainActivity에서 통신하여 데이터를 Recyclerview에 뿌리는 과정

package leeyuri.mobile.retrofittest;

import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class MainActivity extends AppCompatActivity {
    RetrofitClient retrofitClient;
    RetrofitInterface retrofitInterface;

    RecyclerView recycler;

    String API_KEY = "본인이 발급받은 API KEY";

    List<DailyBoxOfficeList> dailyBoxOfficeList_list = new ArrayList<>();
    BoxOfficeAdapter boxOfficeAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recycler= findViewById(R.id.recycler);

        retrofitClient = RetrofitClient.getInstance();
        retrofitInterface = RetrofitClient.getRetrofitInterface();
        
        //key와 날짜 데이터를 넣어서
        retrofitInterface.getBoxOffice(API_KEY, "20210127").enqueue(new Callback<Result>() {
            @Override
            //응답이 올경우
            public void onResponse(Call<Result> call, Response<Result> response) {
            //응답이 성공적으로 얻어져왔을때
                if (response.isSuccessful()){
                    Result result = response.body();
                    BoxOfficeResult boxOfficeResult = result.getBoxOfficeResult();
                    List<DailyBoxOfficeList> dailyBoxOfficeLists = boxOfficeResult.getDailyBoxOfficeList();
                    for (DailyBoxOfficeList dailyBoxOfficeList : dailyBoxOfficeLists){
                        dailyBoxOfficeList_list.add(dailyBoxOfficeList);
                    }

					//데이터를 추가하여 완성한 리스트를 adapter에 설정하고 recyclerview와 연결
                    boxOfficeAdapter = new BoxOfficeAdapter(dailyBoxOfficeList_list, MainActivity.this);
                    recycler.setAdapter(boxOfficeAdapter);
                }
            }
            @Override
            public void onFailure(Call<Result> call, Throwable t) {

            }
        });

    }
}

 

소스코드 링크

 

Reference

youngest-programming.tistory.com/77

 

[안드로이드] Retrofit2 정리 예제

이번에는 레트로핏(Retrofit2)에 대해 정리해보는 포스팅을 가져보도록 하겠습니다. http://www.kobis.or.kr/kobisopenapi/homepg/main/main.do 영화진흥위원회 오픈API www.kobis.or.kr 레트로핏 실습을 위해 영..

youngest-programming.tistory.com

velog.io/@dongchyeon/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-Retrofit2%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%B4-Open-API%EB%A1%9C%EB%B6%80%ED%84%B0-%EC%A0%95%EB%B3%B4-%EC%96%BB%EC%96%B4%EC%98%A4%EA%B8%B0

 

반응형