본문 바로가기

APP 프로젝트/Toy project

1. Android Retrofit - POST 이용하기

프로젝트에 대한 전체적인 설명을 이틀 정도 숙지하고 난 후에 약 이틀간 안드로이드에서 REST API로 통신할 수 있는 Retrofit을 공부했다. 방학 동안 잠깐 찍먹했던 경험이 있어서 할만 하겠다는 생각을 했는데, 생각보다 어렵고 추상적이었다.  

 

어플의 기본 로그인은 소셜 로그인, 그 중에서도 카카오 로그인을 사용하는데, 카카오 로그인에서 발급받은 token을 서버에서 다시 확인하고, 유효한 토큰인지에 대한 몇 가지 단계에 거쳐 응답을 보내준 후 유저가 추가정보를 입력하면 로그인이 되는 패턴이다. 그 중 제일 첫번째 단계인 "카카오 로그인 토큰을 서버에 보내기"는 POST method를 사용해 구현했다. 

 


먼저 retrofit을 빌드하는 코드는 다음과 같다. 싱글턴 패턴을 사용하여 RetrofitClient라는 클래스 (클래스의 이름은 상관 없다.) 를 선언하여 retrofit client를 선언했다. getClient( baseUrl : String ) 메소드는 retrofit 빌더를 사용해 retrofitClient가 null일 경우 선언하고, null이 아닐 경우 원래의 것을 return해주는 메소드이다. 

 

retrofitClient = Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(client.build())
                .addConverterFactory(GsonConverterFactory.create())
                .build()

 

여기서 baseUrl의 경우 서버의 base url을 넣어주고, addConverterFactory의 경우 나는 Gson이라는 json converter을 사용했다. Gson은 java 객체를 json으로 혹은 그 반대로 convert해주는 라이브러리이다. gradle에 추가해 사용할 수 있다.

 

그 위에 보이는 client의 경우는 loggingInterceptor을 사용하고자 했기 때문에 추가했다. loggingInterceptorPOST를 보내고 응답을 받는 과정을 포함해 서버와 통신하는 과정에서 말 그대로 intercept를 하여 로그를 찍어 보고 싶을 때 사용한다. 위에서 나는 setLevel을 통해 Body 레벨의 로그를 보고싶다고 설정하였기 때문에, 아래와 같이 오류가 났을 때 body 수준에서 로그를 볼 수 있었다. 아래와 같이 로그가 찍혀서 어떤 부분이 잘못되었는지 확인하기 위한 용도로 많이 쓰인다. 

 

 

이렇게 retrofit을 선언하고 난 후에는 interface를 통해 method를 정의했다. 이 게시물에서는 일단 가장 첫번째 setPostToken( )에 대해서만 다룬다. POST GET 등을 이용해 어떤 메소드인지를 먼저 정의하고, @Headers는 서버에서 header에 담겨 오기를 바라는 요소를 추가해준다. 마지막으로 @Body는 서버로 전달할 json요청의 body부분에 들어갈 내용을 담을 수 있다. 이 파일은 인터페이스이기 때문에 파라미터와 반환값을 선언해주고 실제 사용은 다른 코드에서 한다. 

 

 

우리 프로젝트에서는 소셜 로그인으로 카카오 로그인을 사용했는데, 카카오 로그인 후 OAuth accessToken을 받는 방법은 카카오 API를 사용했다. 서버사이드와 약속한 대로, 그렇게 받은 accessToken을 POST method의 파라미터로 넘겨주었다.

 

 

메인 코드의 간결함을 위해 RetrofitManager라는 매니징 파일에서 메소드를 먼저 정의해줬다. setPostToken의 메소드를 통해 json의 body 파트에 들어갈 파라미터의 data class는 아래 RetrofitPostRequestDto 파일을 참고하면 된다. 서버에서 오는 응답을 처리하는 방식은 아직 다듬는 중이라 완성되고 난 후에 기록할 예정이다. 

 

 

이렇게 메소드를 정의해주고 난 후에는 메인 코드에서 사용하기만 하면 된다.

 

// activity에서 사용
RetrofitManager.instance.setPostToken(accessToken = token)

 

RetrofitMangersetPostToken을 사용한다는 의미로 이렇게 만들어주면 의도한 대로 서버에 POST가 잘 보내진다. 

 


어제 이렇게 코드를 작성하고 난 후에 계속 500 internet service error가 떠서 세 네 시간동안 이것저것 찾아보면서 해결하려 했지만 결국 해결하지 못했었다. 앞에서 설명한 loggingInterceptor을 찍어봐도 계속 같은 결과만 나와서 서버 쪽 로그를 확인해보니 내가 body 부분을 비우고 계속 요청을 보내고 있었다. 아무리 생각해도 답이 나오지 않아서, 다시 한번 하나하나 뜯어 보니 의외의 장소에서 문제를 발견했다..

 

바로 Content-type: 'application/json' 부분에서 이 전체를 "Content-type: application/json'" 이렇게 따옴표로 감싸야 하는데, 문서화 되어 있는 그대로 "Content-type: 'application/json' " 이렇게 감싼 채로 요청을 보내고 있었다... 이 부분을 고치니 바로 정상적으로 요청이 보내졌고, 서버에서 응답도 제대로 오는 것을 확인할 수 있었다.

 

 

이제 나머지 GET 과 POST를 다시 학습하면서 로그인 과정을 완성해 나갈 예정이다!