-
웹서버의 데이터를 받아오자! Retrofit2Android/Network 2019. 6. 17. 22:58
이번시간은 Retrofit2! 어디선가 들어보았다...
MVVM할때 많은 예제들이 Retrofit2을 사용한 것을 보았다.
Retrofit2는 REST통신을 위한 클라이언트 라이브러리다!
기존에는 아파치를 사용하였는데 왜 이걸 사용해야 하는지는 아래 사진 한장으로 설명
Apache HTTP 클라이언트 사망선고를 맞아서 그에 맞는 Retrofit으로 갈아타야 된다.
HttpURLConnection은 코드량이 어마무시하게 늘어난다.
그래서 Retrofit 이라는 걸 사용하는데 ( 물론 Volley도 있다 )
아래에서 한번 다루어 보도록 하겠당
사전에 알아보는 REST ( 정리가 매우 잘 되어 있습니다 )
https://meetup.toast.com/posts/92
gradle dependency
// retrofit2
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
// okHttp3
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.2'
다시 한번 정의 하자면
Retrofit = REST API를 구현한 상태 간단하게 GET POOSET PUT DELETED를 전달시 서
버에서 처리후 xml, json, text, rss 등으로 응답을 받음
그러면 어떻게 사용하냐면?
Retrofit은 interface을 정의하고, 이 interface class을 Retrofit에 초기화를 하는 과정을 거치면,HTTP 통신을 할 준비가 완료된다.
아래코드는 GitHub에서 제공하는 API 중 user와 관련된 부분을 불러오는 부분이다.
interface Service로 정의하고, @GET annotation을 추가하고 다음을 정의해보자.interface GithubService { @GET("users/{owner}/repos") fun getRepos(@Path("owner") owner: String): Call<List<GithubRepo>> }
GET은 데이터를 가져오는 동사!
Path는 Get에 있는 { } 에 해당 파라미터를 넣는다는 어노테이션이다.
@Path말고 @Query도 있다 이름과 같이 ? 쿼리를 쓸때 사용한다.
간단하게 깃허브에서 해당 유저의 레포지토리 목록을 가져오는 것이 완료되었다.
다음과 같이 Retrofit을 초기화하자. 간단하게 baseUrl을 적어서 초기화할 수 있다.
Retrofit을 생성하면, 위에서 생성한 GithubClient 을 retrofit을 통해 생성한다.class GithubClient { companion object { val BASE_URL = "https://api.github.com" } fun getService(): GithubService { return Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build() .create(GithubService::class.java) } }
baseUrl : 기본적인 Url을 말한다
ConverterFactory : 서버에서 가져오는 데이터를 어떻게 파싱할지 선택하면 된다.
( 기본적으로 Json으로 많이 데이터를 가져오고 github또한 Json으로 반환된다. )
[ 데이터 구조 ]
data class GithubRepo( val name: String, val private: String, val owner : Owner ) data class Owner( val login: String, val url: String )
이후부터는 service을 통해서 Retrofit을 사용하면 된다.
val github = GithubClient()
이제 실제로 값을 가져와 보도록 하자
github.getService().getRepos("You-Kkomi").enqueue(object : Callback<List<GithubRepo>> { override fun onFailure(call: Call<List<GithubRepo>>, t: Throwable) { Log.e("dundun",t.toString()) } override fun onResponse(call: Call<List<GithubRepo>>, response: Response<List<GithubRepo>>) { if (!response.isSuccessful) { return } response.body()!!.forEach { repo -> Log.d("donghun-retrofit", repo.toString()) } } })
enqueue메서드의 Callback 함수를 구현해주자!
깃허브 섭서비스에서 본인의 레포지토리를 반환한다.
데이터가 성공적으로 들어온다면 Log를 찍고
아닐 경우 해당 오류를 로그로 찍는다.
[ 결과 ]
GithubRepo( name=Refactoring-MVVM-using-AAC, private=false, owner= Owner( login=You-Kkomi, url=https://api.github.com/users/You-Kkomi ) )
값은 제대로 들어오는데 통신은 어찌 되는지 궁금하다면 아래와 같이 코드를 변경해보자
private fun createOkHttpClient(): OkHttpClient { val builder = OkHttpClient.Builder() val interceptor = HttpLoggingInterceptor() interceptor.level = HttpLoggingInterceptor.Level.BODY builder.addInterceptor(interceptor) return builder.build() } fun getService(): GithubService { return Retrofit.Builder() .baseUrl(BASE_URL) .client(createOkHttpClient()) .addConverterFactory(GsonConverterFactory.create()) .build() .create(GithubService::class.java) }
[ 로그 ]
D/OkHttp: <-- 200 OK https://api.github.com/users/You-Kkomi/repos (1290ms) D/OkHttp: Date: Mon, 17 Jun 2019 13:18:26 GMT D/OkHttp: Content-Type: application/json; charset=utf-8 D/OkHttp: Transfer-Encoding: chunked D/OkHttp: Server: GitHub.com D/OkHttp: Status: 200 OK D/OkHttp: X-RateLimit-Limit: 60 D/OkHttp: X-RateLimit-Remaining: 59 D/OkHttp: X-RateLimit-Reset: 1560781106 D/OkHttp: Cache-Control: public, max-age=60, s-maxage=60 D/OkHttp: Vary: Accept D/OkHttp: ETag: W/"dd3e2395e06be4972850c8131018c94e" D/OkHttp: X-GitHub-Media-Type: github.v3; format=json D/OkHttp: Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type D/OkHttp: Access-Control-Allow-Origin: * D/OkHttp: Strict-Transport-Security: max-age=31536000; includeSubdomains; preload D/OkHttp: X-Frame-Options: deny D/OkHttp: X-Content-Type-Options: nosniff D/OkHttp: X-XSS-Protection: 1; mode=block D/OkHttp: Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin D/OkHttp: Content-Security-Policy: default-src 'none' D/OkHttp: Vary: Accept-Encoding D/OkHttp: X-GitHub-Request-Id: A7D4:17B2:1882ED5:1D9F714:5D079321 D/OkHttp: // repo json D/OkHttp: <-- END HTTP (25899-byte body)
다음 강좌는 Rx를 사용하여 서버에 데이터 요청시 Call이 아닌 Single로 받아오는 법을 알아보자
'Android > Network' 카테고리의 다른 글
Volley를 이용한 HTTP 통신 (0) 2019.07.23 HttpURLConnection을 이용한 HTTP 통신 (0) 2019.07.22 안드로이드 네트워크 프로그래밍 HTTP 통신 (1) 2019.07.18