retrofit을 테스트해보기 위해 아래 블로그를 참고했다
[Kotlin][Android] retrofit2 이용한 HTTP 통신
코틀린을 통해 간단한 http 통신을 테스트 해보겠습니다. 간단한 GET, POST 요청을 진행할 예정입니다. 서버쪽은 간단한 php 코드를 이용하였고 상세한 세팅과 코드는 생략하였습니다. 포스팅에서
stickode.tistory.com
모델 클래스 선언
DataModels.kt에 선언
package com.asiae.retrofit2test
data class HTTP_GET_Model(
var something: String? = null,
var users: ArrayList<UserModel>? = null
)
data class UserModel(
var idx: Int? = null,
var id: String? = null,
var nick: String? = null
)
data class PostModel(
var id: String? = null,
var pwd: String? = null,
var nick: String? = null
)
data class PostResult(
var result: String? = null
)
APIS 라는 인터페이스를 만드는 과정에서 @Headers가 잘 이해되지 않았다.
깡샘 안드로이드 책에서는 @Headers가 서버 요청에서 헤더값을 조정하고 싶을 때 사용하는 것이라고 되어있었는데
헤더의 개념이 무엇인지 잘 이해되지 않았다.
헤더의 개념을 구글링해보다가 헤더를 알기 위해서는 HTTP의 기본 구조부터 알고 있어야 하는 것 같아 아래의 블로그를 참고했다
(Computer Science > --Network 카테고리의 내용들을 처음부터 찬찬히 살펴봄)
[HTTP-Header] HTTP 헤더란? 그리고 Header의 종류
HTTP 헤더는 클라이언트와 서버가 요청 또는 응답으로 부가적인 정보를 전송할 수 있도록 한다. 우리가 지난 시간에 HTTP 메시지에 대해서 알아보았을 때, 다음과 같은 메시지가 클라이언트, 서버
wonit.tistory.com
위의 블로그를 통해 헤더에 대한 기본 개념을 좀 잡은 상태에서 아까 봤던 코드에 대한 설명을 gpt를 통해 살펴봤다
서비스 인터페이스 정의
@POST("/users")
@Headers("accept: application/json", // 클라이언트가 서버로부터 JSON 형식의 응답을 기대
"content-type: application/json") // 요청의 본문(content)이 JSON 형식
fun post_users(
@Body jsonparams: PostModel
): Call<PostResult>
- @POST("/users") : POST 메서드를 사용해 지정된 엔드포인트인 "/user"로 요청을 보냄
- @Headers("accept: application/json", "content-type: application/json") : POST 요청에 대한 헤더를 설정
- "accept: application/json" : 클라이언트가 JSON 형식의 응답을 기대한다
- "content-type: application/json" : 요청의 본문이 JSON 형식
- fun post_users(@Body jsonparams: PostModel) : Call<PostResult> : 이 메서드는 POST 요청을 수행하는데 사용되며, 'jsonparams'를 요청의 본문으로 보냄
- PostModel : 요청 본문의 구조를 정의하는 모델 클래스
- Call<PostResult> : 서버로부터 예상되는 응답의 형태를 정의하는 Retrofit의 'Call' 객체
위 코드는 안드로이드 앱에서 Retrofit을 사용해 "/users" 엔드포인트로 JSON 형식의 데이터를 POST 요청하고, 서버로부터 'PostResult' 객체를 받아올 때 사용
@GET("/users")
@Headers("accept: application/json",
"content-type: application/json"
)
fun get_users(
): Call<HTTP_GET_Model>
위의 코드는 이전에 봤던 코드와 비슷하지만 다르다.
위 코드는 Retrofit을 사용하여 GET 요청을 보내고 "/user" 엔드포인트로부터 JSON 형식의 데이터를 받아오기 위한 것이다
- @GET("/users") : GET 메서드를 사용해 "/user" 엔드포인트로 요청을 보냄
- @Headers("accept: application/json", "content-type: application/json") :요청에 대한 헤더를 설정
- "accept: application/json" : 클라이언트가 JSON 형식의 응답을 기대한다
- "content-type: application/json" : 요청의 본문이 JSON 형식
하지만 GET 요청은 일반적으로 본문이 없으므로 "content-type" 헤더는 보통 사용되지 않음
- fun post_users() : Call<HTTP_GET_Model> : 이 메서드는 GET 요청을 수행하고, 서버로부터 받은 응답을 'HTTP_GET_Model' 객체로 변환해 반환
- HTTP_GET_Model : 서버에서 받아온 JSON 응답을 파싱하여 해당 데이터를 포함하는 데이터 클래스
따라서 이 코드는 "/user" 엔드포인트로 GET 요청을 수행하고, 서버로부터 JSON 형식의 응답을 'HTTP_GET_Model' 객체로 변환해 받아옴
Retrofit 객체 생성
companion object {
private const val BASE_URL = "http://234.234.234.33:7712" // 주소
fun create() : APIS {
val gson: Gson = GsonBuilder().setLenient().create();
return Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
.create(APIS::class.java)
}
}
- companion object : 이 블록은 클래스의 인스턴스 없이 클래스에 속한 메서드와 변수를 사용할 수 있게 해주는 Kotlin의 기능. 이 경우에는 'create()' 메서드를 정의하여 Retrofit 인스턴스를 만듦
- private const val BASE_URL : 기본 URL 주소를 저장하는 상수. 이 URL은 앱이 통신할 서버의 기본 주소를 나타냄
- fun create() : APIS : Retrofit 인스턴스를 생성하여 반환하는 함수. 이 함수는 Retrofit.Builder를 사용해 Retrofit 객체를 만들고, 해당 Retrofit 객체를 통해 서비스 인터페이스(APIS)를 생성해 반환
- val gson: Gson = GsonBuilder().setLenient().create() : Gson을 커스터마이징하여 JSON 파싱을 유연하게 처리하도록 하는 부분. setLenient()은 JSON 파싱에서 유연성을 확보하기 위한 설정
- Retrofit.Builder() : Retrofit 객체를 생성하는데 사용됨. 기본 URL, 컨버터 팩토리(Gson), 그리고 기타 설정을 여기에 추가 가능
- addConverterFactory(GsonConverterFactory.create(gson)) : Retrofit이 서버 응답을 파싱하는데 사용할 Gson 인스턴스 설정
- .create(APIS::class.java) : 마지막으로, Retrofit 객체를 생성하고 'APIS' 인터페이스를 구현한 서비스 생성. 이 서비스를 통해 앱은 서버로부터 데이터를 받거나 보낼 수 있음
GET 요청 버튼 구현
MainActivity.kt에 구현된 GET요청 버튼 클릭하는 부분이다.
아래 코드는 안드로이드 앱에서 'GET요청' 버튼을 클릭할 때 Retrofit을 사용해 서버로부터 데이터를 가져오는 예시
클릭 이벤트가 발생하면 api.get_users()를 호출해 서버로부터 데이터를 가져오고, 이를 처리하기 위해 Retrofit의 enqueue 메서드 사용
// get 요청 버튼 클릭
binding.getbutton.setOnClickListener {
api.get_users().enqueue(object : Callback<HTTP_GET_Model> {
override fun onResponse(call: Call<HTTP_GET_Model>,
response: Response<HTTP_GET_Model>) {
Log.d("log",response.toString())
Log.d("log", response.body().toString())
if(!response.body().toString().isEmpty())
binding.text.setText(response.body().toString());
}
override fun onFailure(call: Call<HTTP_GET_Model>, t: Throwable) {
// 실패
Log.d("log",t.message.toString())
Log.d("log","fail")
}
})
}
enqueue() 함수를 호출하면 비로소 통신이 수행됨
그리고 enqueue() 함수의 매개변수로 지정한 Callback 객체의 onResponse(), onFailure() 함수가 자동으로 호출됨
- 통신 성공 : onResponse() 함수 호출
- 통신 실패 : onFailure() 함수 호출
통신에 성공하면 서버에서 넘어온 데이터가 onResponse() 의 매개변수인 Response 객체로 전달되며 이 데이터를 response.body() 함수로 얻을 수 있음
위 코드를 보면 Response<HTTP_GET_Model>로 선언했으므로 response.body() 함수가 반환하는 값은 HTTP_GET_Model 객체
즉, 제네릭으로 선언한 클래스의 객체에 담아서 전달해줌
POST 요청 버튼 구현
MainActivity.kt에 구현된 POST요청 버튼 클릭하는 부분이다.
아래 코드는 안드로이드 앱에서 'POST버튼'을 클릭할 때 Retrofit을 사용해 서버로 데이터를 전송하는 예시를 보여줌
클릭 이벤트가 발생하면 'PostModel' 객체를 생성하여 사용자가 입력한 데이터를 담음
그런 다음, 'api.post_users(data)'를 호출하여 서버로 데이터 전송
//post요청 버튼 클릭
binding.postbutton.setOnClickListener {
val data = PostModel(
binding.idedt.text.toString(),
binding.pwdedt.text.toString(),
binding.nickedt.text.toString())
api.post_users(data).enqueue(object: Callback<PostResult>{
override fun onResponse(call: Call<PostResult>, response: Response<PostResult>) {
Log.d("log", response.toString())
Log.d("log", response.body().toString())
if(!response.body().toString().isEmpty())
binding.text.setText(response.body().toString())
}
override fun onFailure(call: Call<PostResult>, t: Throwable) {
Log.d("log", t.message.toString())
Log.d("log", "fail")
}
})
}
enqueue() 함수를 호출하면 비로소 통신이 수행됨
그리고 enqueue() 함수의 매개변수로 지정한 Callback 객체의 onResponse(), onFailure() 함수가 자동으로 호출됨
- 통신 성공 : onResponse() 함수 호출
- 통신 실패 : onFailure() 함수 호출
통신에 성공하면 서버에서 넘어온 데이터가 onResponse() 의 매개변수인 Response 객체로 전달되며 이 데이터를 response.body() 함수로 얻을 수 있음
위 코드를 보면 Response<PostResult>로 선언했으므로 response.body() 함수가 반환하는 값은 PostResult 객체
즉, 제네릭으로 선언한 클래스의 객체에 담아서 전달해줌
AVD 애뮬레이터 실행 결과
초기 화면
코드를 다 작성하고 애뮬레이터를 실행했는데 get요청 버튼 post요청 버튼이 모두 동작하지 않았다. 초기값이라고 적힌 부분이 바뀌어야 하는데 그대로였다.
baseUrl의 문제 같긴한데 결국 해결하지는 못했다...
logCat을 확인해보니
Failed to connect to /234.234.234.33:7712
라고 떴다
baseUrl의 문제가 맞는 것 같다 하지만 해결하지 못했다...
완성 github는 retrofitTest폴더 안에 있다
GitHub - rosa2070/MinorAndroid: 마이너 안드로이드 플젝(뮤지컬리언즈)
마이너 안드로이드 플젝(뮤지컬리언즈). Contribute to rosa2070/MinorAndroid development by creating an account on GitHub.
github.com