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
4. Pojo 클래스 생성
json 데이터를 받아올 껍데기 클래스인 Pojo 클래스를 생성해야한다.
위 사이트에서 영화진흥위원회 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
'Android' 카테고리의 다른 글
[Android/kotlin] spinner 커스텀해서 사용하기 (0) | 2021.03.07 |
---|---|
[Android/kotlin] DialogFragment를 이용한 커스텀 대화상자 만들기 (0) | 2021.03.05 |
[Android] 팔레트 항목 뜯어보기 (0) | 2021.01.21 |
[Android] AsyncTask 클래스 (0) | 2021.01.20 |
[Android] 스레드(Thread)와 핸들러(Handler) (0) | 2021.01.20 |