0. 종속성 추가
Retrofit2를 사용하기 위해서는 먼저 app 모듈의 build.gradle에 종속성을 추가해야 합니다. Retrofit2의 최신 버전은 https://github.com/square/retrofit에서 확인할 수 있습니다.
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
1. Manifest에 권한 추가
RestAPI를 통해 데이터를 받아오기 위해서는 인터넷이 필요하므로 manifest 파일에 Internet 권한을 추가해야 합니다.
<uses-permission android:name="android.permission.INTERNET"/>
2. RetrofitClient Object 생성
통신할 baseUrl
을 설정하고 데이터 파싱 및 객체 정보를 반환할 수 있는 Retrofit 객체와 Json을 Kotlin Object로 변환시켜줄 Gson 객체를 생성하는 부분을 싱글톤(Object)으로 만들어줍니다.
먼저, baseUrl
은 고정된 주소로 지정합니다. 저는 "http://IP_주소/UserInsert.php", "http://IP_주소/UserSelect.php" 등 여러 PHP과 통신을 해야하기 때문에 "http://IP_주소/"를 baseUrl로 지정했습니다. 중요한 점은 baseUrl
은 꼭 ‘/’로 끝나야 오류가 생기지 않는다는 점입니다.
그리고 addConverterFactory(GsonConverterFactory.create(gson))
은 Json 데이터를 POJO Class 형식으로 자동변환하기 위해 필요합니다.
import com.google.gson.GsonBuilder
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
object RetrofitClient {
private var instance : Retrofit? = null
private val gson = GsonBuilder().setLenient().create()
fun getInstance() : Retrofit {
if(instance == null){
instance = Retrofit.Builder()
.baseUrl("http://${IP_ADDRESS}/")
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
}
return instance!!
}
}
3. POJO Class 생성
제가 생성한 PHP 파일에서는 아래와 같은 Json 데이터를 반환합니다.
// UserSelect.php
// 로그인 성공 시
echo json_encode(array(
"status" => "true",
"message" => "로그인 성공"
"email"=>$row["email"],
"password"=>$row["password"],
"username"=>$row["username"],
"picture"=>$row["picture"],
), JSON_UNESCAPED_UNICODE);
// 로그인 실패 시
echo json_encode(array(
"status" => "false",
"message" => "로그인 실패"
), JSON_UNESCAPED_UNICODE);
// 로그인 성공 시
{
"status" => "true",
"message" => "로그인 성공"
"email":"rit@abc.com",
"password":"123456",
"username":"RIT",
"picture":"rit@abc.com/profile.JPG"
}
// 로그인 실패 시
{
"status" => "false",
"message" => "로그인 실패"
}
위와 같은 Json 데이터를 받을 POJO Class는 아래와 같습니다. PHP에서 반환되는 Json의 Key 값과 Data Class의 속성명과 변수명 + 타입(ex String,Int,Boolean) 일치는 필수입니다. 혹은 @SerializedName
어노테이션을 통해 Json의 Key 값과 같도록 만들어줘야 합니다.
data class User (
val email : String?,
val user_name : String?,
val gender : String?,
val picture : String?,
val status : String?,
val message : String?
)
4. API Interface 생성
저는 POST 방식으로 PHP로 데이터를 보내고, 가져오는 것을 선택했습니다. @POST
는 위에서 지정해둔 baseUrl의 뒤에 오는 "UserInsert.php"이나 "UserSelect.php" 같은 상세 주소를 지정하고, 동적으로 변경해야 하는 파라미터는 @Field
어노테이션을 이용해서 PHP에 보낼 데이터의 형식을 정해줍니다. 마지막으로 PHP로부터 Json을 반환받는다면 POJO Class로 받을 수 있도록 Call
을 return type으로 정해줍니다.
import retrofit2.Call
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.POST
interface UserAPI {
@FormUrlEncoded
@POST("UserSelect.php")
fun getUser(
@Field("email") email: String
): Call<User>
}
5. Request 보내기
처음에 만들었던 RetrofitClient
를 통해 생성한 Retrofit 객체를 받아오고, 해당 객체를 이용해 Interface를 구현합니다. 통신 방법에는 enqueue
를 이용하는 비동기 작업과 execute
를 이용하는 동기 작업이 있습니다.
비동기 작업으로 실행한다면 통신 종료 후 이벤트 처리를 위해 Callback
을 등록해야 하고, 동기 작업으로 실행한다면 AsyncTask
등을 통해 받아온 데이터를 가지고 UI 작업을 할 수 있습니다.
저는 비동기 작업으로 실행할 것이므로 enqueue
를 이용하였습니다. email로 요청을 보내고 난 다음 결과는 두 가지로 나뉩니다. 통신에 성공했을 경우에는 onResponse
, 통신에 실패했을 경우에는 onFailure
로 나뉘는데 실패했을 경우에는 그에 따른 처리를 해주어야 합니다.
- SigninActivity.kt
val retrofit = RetrofitClient.getInstance()
val server = retrofit.create(UserAPI::class.java)
server.getUser(email).enqueue(object : Callback<User> {
override fun onResponse(
call: Call<User>,
response: Response<User>
) {
Log.d(TAG, "성공 : ${response.body()}")
}
override fun onFailure(call: Call<User>, t: Throwable) {
Log.d(TAG, "실패 : ${t.localizedMessage}")
}
})
- UserSelect.php
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
include("dbcon.php");
$email = $_POST['email'];
if($email == '') {
echo json_encode(array(
"status" => "false",
"message" => "필수 인자가 부족합니다"),
JSON_UNESCAPED_UNICODE
);
} else {
try {
$sql="select * from user_tb where U.email like '$email'";
$stmt = $con->prepare($sql);
$stmt->execute();
if ($stmt->rowCount() == 0) {
echo json_encode(
array(
"status" => "false",
"message" => "로그인 실패"
), JSON_UNESCAPED_UNICODE
);
} else {
while($row=$stmt->fetch(PDO::FETCH_ASSOC)) {
extract($row);
echo json_encode(array(
"status" => "true",
"message" => "로그인 성공",
"email"=>$row["email"],
"password"=>$row["password"],
"user_name"=>$row["user_name"],
"picture"=>$row["picture"]
), JSON_UNESCAPED_UNICODE);
}
}
} catch(PDOException $e) {
die("Database error: " . $e->getMessage());
}
}
}
?>
6. 통신 결과
'Programando > Android' 카테고리의 다른 글
[Android/Kotlin] RecyclerView 사용하기 (0) | 2022.01.12 |
---|---|
[Android/Kotlin] 안드로이드 숫자 국가 코드 (0) | 2021.11.12 |
[Android/Kotlin] ViewPager2, Remote Config_(7) (0) | 2021.08.21 |
[Android/Kotlin] 기기 권한 받아오기_(6) (0) | 2021.06.22 |
[Android/Kotlin] Room_(5) (0) | 2021.06.17 |