본문 바로가기
ⓢⓣⓤⓓⓨ/ⓐⓝⓓⓡⓞⓘⓓⓢⓣⓤⓓⓘⓞ

[Kotlin] Retrofit2

by heaven00 2021. 11. 14.
728x90

          

  

 

Retrofit2가 너무 어렵다..

서버가 너무 어렵다...

그래서 복습했는데도 잘 모르겠어서.. 정리를 하려고 한다..

 

 


 

1. 서버통신 하려면?

✅ Postman

- 서버 파트원과 필요한 데이터 논의 (Postman)

- 서버 API문서 확인 후 테스트 (Postman)

 

 

✅ 구현부분

- 라이브러리 추가 및 AndroidManifest 설정

- 서버 Rquest/Response 객체 설계

- Retrofit Interface 설계

- Retrofit Interface 실제 구현체 만들기

- Callback 등록하여 통신 요청

 

 

 

2. Retrofit2 란?

서버와 클라이언트 간 http 통신을 위한 라이브러리 (OKhttp를 이용해서 더 편하고 사용하기 쉽게 만든 것) 

  • API 통신을 위해 구현된 OkHTTP의 HTTP 통신을 간편하게 만들어주는 라이브러리를 뜻함   객체로 받을 수 있음
  • JSON 구조의 데이터를 쉽게 가져오고 업로드

=> 클라이언트에서 서버로 어떠한 요청을 보내면 서버는 그 요청에 대한 응답을 클라이언트로 보내주게 되는데, 이 일련의 과정들을 쉽게 사용 할 수 있도록 도와줌

 

 

3. Retrofit2 구현

1️⃣ 라이브러리 추가

// 서버 연결을 위한 Retrofit2
    implementation "com.squareup.retrofit2:retrofit:2.9.0"

    // Retrofit2에서 gson 사용을 위한 컨버터
    implementation "com.squareup.retrofit2:converter-gson:2.9.0"

    // gson
    implementation "com.google.code.gson:gson:2.8.6"

 

❗❗ gson 이란? ❗❗

=> Java에서 Json을 파싱하고, 생성하기 위해 사용되는 구글에서 개발한 오픈소스

  • JSON 데이터를 JAVA 객체로 변환 시켜주는 라이브러리.
  • JAVA 객체를 JSON 데이터로 변환 시켜주는 라이브러리.
  • [JSON 데이터 ↔️ JAVA 객체]

⭐ Retrofit2는 gson을 자바 객체로 변환하는 자체 컨버터를 가지고 있지 않는다. 그러므로 컨버터 라이브러리의 경우 Retrofit2에 따로 넣어줘야한다. 

 

 

2️⃣ AndroidManifet 설정

<uses-permission
		//인터넷 접속 권한 부여
        android:name="android.permission.INTERNET" />
    <application
    	//Android9 버전부터는 https 통신을 권장하고 http 통신을 권장하지 않음
        // => http로 통신하려면 해당 속성을 true로 해줘야함.
        android:usesCleartextTraffic="true"

 

 

 

3️⃣ 서버 Request / Response 객체 설정

 

 1) Requset

Request

🔽🔽🔽🔽아래와 깉이 설계🔽🔽🔽🔽

data class RequestLoginData(
    @SerializedName("email")
    val email: String,
    val password: String
)

 

2) Response

Response

🔽🔽🔽🔽아래와 깉이 설계🔽🔽🔽🔽

data class ResponseLoginData(
    val status: Int,
    val success: Boolean,
    val message: String,
    val data: Data
) {
    data class Data(
        val id: Int,
        val name: String,
        val email: String
    )
}

 

 

 

4️⃣ Retrofit Interface 설계

❗❗ Retrofit Interface란? ❗❗

=> 서버에 어떠한 요청을 보내면 어떻게 온다는 일종의 상호작용 방법을 정의하는 부분

=> 서버와의 의사소통 방식만 인터페이스에서 정의하면 Retrofit 구현체에서 알아서 interface를 구현해서 생성해준다.

interface SampleService {	//서버로부터 받아오는 Service를 정의하는 부분
	
    //@Headers 어노테이션 이용해 헤더값 넣어주기
    @Headers("Content-Type: application/json")
    
    //HTTP 메소드를 설정해주고 API와 URL 작성
    @POST("user/login")
    
    fun postLogin(
    	//@Body 어노테이션을 통해 RequestBody 데이터를 넣어준다.
        @Body requestLoginData: RequestLoginData
    ) : Call<ResponseLoginData>
}

 

⭐⭐⭐GET의 경우에는 Body값을 넣어주지 못한다⭐⭐⭐

=> @Query와 @Path를 통해 서버에서 요청하는 정보를 전달

 

* POST, PUT Body값 => ⭕

* GET, DELETE Body값 => ❌

 

 

 

5️⃣ Retrofit Interface 실제 구현체(객체) 만들기

object ServiceCreator {	//서비스를 생성해주는 구현체 부분
    private const val BASE_URL = "uri주소 첨부(메인 서버 도메인)"

	//Retrofit 객체 생성
    private val retrofit: Retrofit = Retrofit
    
        //레트로핏 빌더 생성 (생성자 호출)
        .Builder()	
        
        //빌더 객체의 baseUrl 호출. 서버의 메인 URL 전달
        .baseUrl(BASE_URL)	
        
        //gson 컨버터 연동
        .addConverterFactory(GsonConverterFactory.create())
        
        //Retrofit 객체 반환
        .build()	

	//인터페이스 객체를 create에 넘겨 실제 구현체 생성
    val sampleService : SampleService = retrofit.create(SampleService::class.java)
}

 

 

 

6️⃣ Callback 등록하여 통신 요청

* 서버 관련 부분 코드만 첨부

private fun initNetwork() {

		//서버에 요청을 보내기위한 RequestData 생성
        val requestLoginData = RequestLoginData(
            binding.etId.text.toString(),
            binding.etPassword.text.toString()
        )

		//싱글턴 객체를 이용해 Retrofit이 만들어준 interface 구현체에 접근하여 call 객체 받아옴
        val call: Call<ResponseLoginData> = ServiceCreator.sampleService.postLogin(requestLoginData)
        
        //call 객체에 enqeue를 호출하여 실제 서버통신을 비동기적으로 요청
        call.enqueue(object : Callback<ResponseLoginData> {
            override fun onResponse(
                call: Call<ResponseLoginData>,
                response: Response<ResponseLoginData>
            ) {
            	//Status Code가 200~300 사이일 때, response.isSuccessful은 true를 반환 
                // => 서버통신 성공
                if (response.isSuccessful) {
                    Toast.makeText(
                        this@SignInActivity,
                        "${response.body()?.data?.name}님 반갑습니다",
                        Toast.LENGTH_SHORT
                    ).show()
                    startActivity(Intent(this@SignInActivity, HomeActivity::class.java))
                } else {
                    Toast.makeText(this@SignInActivity, "로그인에 실패했습니다", Toast.LENGTH_SHORT).show()
                }

            }

			//response.isSuccessful이 false이거나 body()에 값이 없을 경우 에러 처리
            // => 서버통신 실패
            override fun onFailure(call: Call<ResponseLoginData>, t: Throwable) {
                Log.e("NetworkTest", "error: $t")
            }

        })
    }

 

 

 


 

안드로이드 스튜디오 공식 문서와 안드로이드 파트장님이 준비해주신 세미나 내용을 참고하면서

직접 이해한 내용을 바탕으로 작성했습니다.

 

포스트맨 관련 내용도.. 꼭 써야지 나중에..

728x90

댓글