민프
[Android][Kotlin] Retrofit2를 사용해보자!! (공공API 사용) 본문
🎈준비하기
https://www.data.go.kr/iim/api/selectAPIAcountView.do
이곳에서 API를 발급 받으면 된다.
🎈Retrofit 이란?
- 안드로이드 http 통신 라이브러리 중 하나이다.
https://square.github.io/retrofit/
🎈Retrofit 추가하기
bulid.gradle(app) 라이브러리 추가
//레트로핏
implementation 'com.squareup.retrofit2:retrofit:2.6.4'
//GSON 컨버터
implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
===============================
Manifest에 인터넷 권한 추가
<uses-permission android:name="android.permission.INTERNET"/>
🎈POJO 클래스 만들기 (나중에 계속하기로)
블로그를 찾아보다가
데이터를 담기위해서 POJO클래스를 만든다고 공통적으로 말하길래
POJO클래스에 대해서 찾아보았는데
POJO란?
어떠한 제한에도 묶이지 않는 자바 오브젝트라 무엇일까..??
일단 POJO 클래스를 만들어주는 사이트에서 POJO 클래스를 만들어보았다.
https://www.jsonschema2pojo.org/
Class 내용을 보면 변수 선언, getter, setter가 전부임을 알 수 있었다.
Retrofit을 이용하여
API를 적용하는 예제를 보면
데이터를 담는 그릇을 만드는 클래스를 만들때
POJO 클래스를 만든다고 하는거 보면
데이터를 담는 작업 외에는 별다는 작업을 하지 않고,
POJO 클래스는 상속과 인터페이스로부터 자유로운것을 확인할 수 있었다.
*POJO클래스를 사용해보려고 했었는데ㅠㅠ 내가 잘 못해서 그런지
JSON 파싱을 해도 String 값으로는 잘 들어오는데 GsonConverter + POJO 클래스 이용하면
자꾸 에러가 떠서ㅠㅠ 일단은 진행중인 프로젝트가 있어서 중단하고 프로젝트가 끝나면 다시 도전해봐야겠다.
당장은
API에서 받은 값들을
JSON Object클래스를 이용해서 JSON 문자열과 JSON 배열을 파싱해서
값들을 데이터Model에 저장하는 방식으로 해야겠다.
나중에.. 언제 시간이날지는 모르겠지만
POJO클래스를 써서 하는 방법을 해봐야겠다ㅠㅠ
🎈Retrofit Inteface 만들기
여기서 Interface는 Retrofit에서 사용할 HTTP CRUD(메소드)들을 정의해놓은 인터페이스 입니다.
*CRUD(Create, Read, Update, Delete) -> HTTP Method(POST/GET/PUT/DELETE)
interface RetroInterface {
@GET("GetWheelchairChargerService/getWheelchairChargerInfo")
fun getBoxOffice(
@Query("serviceKey") key: String?,
@Query("dataType") targetDt: String?
): Call<String>
- @GET => HTTP Method중 하나이고, baseUrl에 연결될 EndPoint 이다.
- 동적 URL
- 서버에 값 보내기
서버에 값을 보낼때에는
@Query
@Field
@Body
가 있는데
차이점은
@Query = @GET에서 사용하며 모든 매개 변수가 요청에 추가되고 사용자에게 표시되고,
@Field = @FormUrlEncoded(=key-Value, ) @POST,에서 사용하며 매개 변수를 숨기고 URL을 추가하지 않는다.
@Body = Gson 컨버터와 함께 쓰이기 때문에, Java Object를 통째로 직렬화 해서 보낼 수 있다.
쉽게 말해서 Json형식으로 보내고 싶을때 사용한다.
- Call<String> = API에서 받은 데이터의 반환타입을 String으로 받겠다는 것 이다.
🎈Retrofit 인스턴스 만들기
Retrofit.Bulid를 통해서 Retrofit 인스턴스를 생성해보자
val KEY = "My Key"
val BASE_URL = "http://apis.data.go.kr/4460000/"
//레트로핏 빌더를 통해 인스턴스 생성
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.build()
/* Timeout 시간 늘리기
* val client: OkHttpClient = OkHttpClient.Builder()
.connectTimeout(300, TimeUnit.SECONDS)
.readTimeout(300, TimeUnit.SECONDS)
.writeTimeout(300, TimeUnit.SECONDS)
.addInterceptor(object :
Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
val newRequest: Request = chain.request().newBuilder()
.addHeader("Authorization", "Bearer " + userAccessTokenValue)
.build()
return chain.proceed(newRequest)
}
}).build()
*/
//Retrofit 인스턴스로 인터페이스 객체 구현
val api:RetroInterface = retrofit.create(RetroInterface::class.java)
//인터페이스에서 정의한 메소드
val callGetSearchNews = api.getBoxOffice(KEY, "JSON")
//enequeue로 비동기 실행, Callback을 String
callGetSearchNews.enqueue(object : Callback<String> {
override fun onResponse(
call: Call<String>,
response: Response<String>
) {
Log.d(TAG, "통신 성공 : ${response.raw()}")
}
override fun onFailure(call: Call<String>, t: Throwable) {
Log.d(TAG, "통신 실패 : $t")
}
})
🎈String To JSON
API 값들을 Callback 값으로 String으로 받았는데요
JSON구조에 맞게 JSON Objest, JSON Array로 나눠보겠습니다.
JSON 구조를 편하게 보기 위해서 밑 사이트를 참고하였습니다.
https://jsonformatter.curiousconcept.com/#
간단하게 JSONArray와 JSONObject를 설명하자면
- JSONArray
- 배열 구조이다.
- '[ ]' 대괄호를 이용하여 값들을 담으며, ' , '로 값을 구분한다.
- => ' { { }, { }, { } } '
- JSONObject
- 하나 이상의 Key-Value 을 '{ }' 의 중괄호를 이용하여 담고있는 객체 구조이다.
- => ' [ { },{ },{ } ] '
그럼 받아온 데이터를 JSONArray, JSONObject로 구분해보자
val KEY = "My Key"
val BASE_URL = "http://apis.data.go.kr/4460000/"
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.build()
val api:RetroInterface = retrofit.create(RetroInterface::class.java)
val callGetSearchNews = api.getBoxOffice(KEY, "JSON")
start = System.currentTimeMillis()
callGetSearchNews.enqueue(object : Callback<String> {
override fun onResponse(
call: Call<String>,
response: Response<String>
) {
// Log.d(TAG, "통신 성공 : ${response.raw()}")
// Log.d(TAG, "통신 성공 : " + response.body().toString())
val jsonObject = JSONObject(response.body().toString())
Log.d(TAG+ " jsonObjectResponse", jsonObject.toString())
//JsonObject, JsonArrary 구조 나누기
val jsonObjectResponse = jsonObject.getJSONObject("response")
val jsonObjectHeader = jsonObjectResponse.getJSONObject("header")
val jsonObjectBody = jsonObjectResponse.getJSONObject("body")
val jsonObjectItems = jsonObjectBody.getJSONObject("items")
val jsonArraryItem = jsonObjectItems.getJSONArray("item")
//response{ } -> header{resultCode, resultMsg}값 추출
val resultCode = jsonObjectHeader.getInt("resultCode")
val resultMsg = jsonObjectHeader.getString("resultMsg")
Log.d(TAG+ " resultCode", resultCode.toString())
Log.d(TAG+ " resultMsg", resultMsg.toString())
//response{ } - body{ } -> items[ ] -> item{ } 값 추출
Log.d(TAG+ " jsonArraryItem ", jsonArraryItem.length().toString())
for (i in 0..jsonArraryItem.length()-1){
Log.d(TAG+ " i", i.toString())
val getObject = jsonArraryItem.getJSONObject(i)
val lotnoAddr = getObject.getString("lotnoAddr")
val fcNm = getObject.getString("fcNm")
Log.d(TAG+ " lotnoAddr", lotnoAddr.toString())
Log.d(TAG+ " fcNm", fcNm.toString())
}
}
override fun onFailure(call: Call<String>, t: Throwable) {
Log.d(TAG, "통신 실패 : $t")
}
})
잘 나오는 것을 확인할 수 있다.
'[Android]' 카테고리의 다른 글
[Android][Kotlin] EditText 입력 변경 이벤트 (addTextChangedLitener) (0) | 2021.09.25 |
---|---|
[Android][kotlin] JetPack - Navigation으로 Fragment 화면 전환 및 데이터 전송해보기! (0) | 2021.09.24 |
[Android][Kotlin] CustomDialog로 엑티비티에 값을 전달해보자 (0) | 2021.09.22 |
[Android][Kotlin] 안드로이드 사이드 메뉴바를 구현해보자 (DrawerLayout) (0) | 2021.09.07 |
[Android][Kotlin] 카카오 로그인 구현해보기! (API 이용)(Feat.KOE004) (0) | 2021.09.06 |