모름

간단하게 RetroFit Post 적용할 수 있는 순서에대한 설명글입니다. 기반지식이 없는 상태에서 Retrofit을 적용하려니 꽤 힘들었었습니다. 그래서 답답했던 마음에, 혹시라도 저처럼 해매지 마시라고, Retrofit 사용의 전체적인 그림이해를 편하게 하셨으면 하는 마음에 작성합니다.

 

 

 

 

1. Manifast.xml 에 인터넷 퍼미션 추가

= Retrofit을 사용하기위해 인터넷 사용권한을 추가해주는것입니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.eyedoc">

    <!--    retrofit 사용을 위한 인터넷 사용권한 추가-->
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        ...블라블라 기존에있는 내용
    </application>

</manifest>

인터넷 사용권한 추가 주석 아래의 줄 <uses-permission android:name="android.permission.INTERNET" /> 복사해서 붙여넣어주세요. 말그대로 인터넷 사용 권한에 대한 승인을 해줍니다.

 

 

 

 

 

 

 

2. (선택사항) 바로 이어서 Manifast.xml의 <application 에 설정 추가>

= http://~ 프로토콜(주소)의 api도 접근이 가능하게 합니다_프로젝트 버젼에 따라 다름

    <application
        android:"블라블라"
        .
        .
        .
        android:usesCleartextTraffic="true">
        
        
    </application>

android:usesCleartextTraffic="true" 이걸 추가해줍니다. 이것은 선택사항입니다. 프로젝트 버젼이 Pie(?)였나, 일정 버젼 이상으로는 앱 통신시 http:// 주소로는 통신이 불가능하고 htttps://로만 통신이 가능하게 제약이 걸려있다고 합니다. 만약 사용하려는 api 주소가 http://면 해당 문구를 넣어줌으로서 접속이 가능하게 해주도록 합니다.

 

 

 

 

 

 

 

3. Module / build.gradle 에 아래 디펜던시를 추가합니다.

= Retrofit과 Retrofit gson converter는 각각 통신, json 컨버터 작업을 도와줍니다.

dependencies {
	//Retrofit - default
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    //Retrofit - gson
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
}

implementation 'com.squareup.retrofit2:retrofit:2.9.0'implementation 'com.squareup.retrofit2:converter-gson:2.9.0' 을 추가해주세요. 만약 버젼이 더 높은게 있다면, 해당 버젼 부분 (*2.9.0)이 노란색으로 마킹돼 보여질텐데 alt+enter를 누르고 최신 업데이트를 자동으로 추천받을 수 있습니다.

 

간단하게 뭔지 설명드리자면, default는 retrofit 라이브러리를 의미하고, gson converter는 json 형식으로 받아올 데이터를 안드로이드 스튜디오에서 사용가능한 객체로 변환시켜줍니다.  (저도 대강 이렇게만 이해하고 있으므로 자세한건 따로 알아보기)

 

 

 

 

 

 

4. (선택사항) Java 1.8 콤파일 옵션을 추가해주세요.

= 그냥 해야할것같아서

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"

    defaultConfig {
        블라블라
    }

    buildTypes {
        블라블라
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

자바 1_8버젼을 적용해야 retrofit이 되는건지 필수요건인건 아니지만, 딱히 안할 이유가 없습니다. 자바에서 람다식을 사용할수있게해줍니다.  

 

 

 

 

 

 

 

(클래스명은 바꿔도됩니다)

5. RetrofitClient.class 를 추가해주세요. 아래 내용을 복붙하시면 됩니다

= api호출의 시작점으로 활용할 클래스이며 앞서 설치한 Retrofit의 클래스를 생성하고 앞으로 작성할 api클래스를 Retrofit.class에 연결시켜주는 역할을 합니다.

package 여러분의 패키지네임, 이건 복사하지마세요.;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitClient {
    private static final String BASE_URL = "http://여러분의 api주소/";

    public static RetrofitAPI getApiService(){return getInstance().create(RetrofitAPI.class);}

    private static Retrofit getInstance(){
        Gson gson = new GsonBuilder().setLenient().create();
        return new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();
    }
}

 

내용을 복사하면 RetrofitApi 클래스가 없기때문에 오류가 날것입니다. 다음단계에서 만들것입니다.  우선 해당 클래스의 변수 BASE_URL 스트링에 여러분이 쓸 api링크를 넣어주세요. 

 

(아래부터는 해당 클래스에 대한 설명인데 무시하고 넘어가셔도됩니다.)

그리고 여러분은 이 클래스를 통해서 api에 접근하게 됩니다. 즉, 이게 api를 부를때 사용해야할 첫번째 클래스(시작점)라는 의미입니다. 예를 들어 아래와 같이말입니다.

RetrofitClient.getApiService().//api콜//

여기서 getApiService()를 호출하게되면 RetrofitApi를 반환해야합니다. 이 반환은 해당 클래스의 getInstance()에서 리턴되는 Retrofit클래스의 create(//인자로 api.class를 넘겨줌)함수를 통해 이루어집니다.

 

*주의사항 : api주소의 끝부분이 ' / (슬래쉬) ' 로 끝나도록 강제되고 있으므로 주소입력시 이를 참고해서 혹여나 링크에 슬래쉬가 겹쳐지는 경우가 발생하지 않도록 해주세요.

 

 

 

 

 

 

 

(클래스명은 바꿔도됩니다)

6.RetrofitAPI 인터페이스를 생성해 아래 내용을 복붙해주세요.

= api콜들을 정의내리고 사용하기 쉽게 정리해놓는 클래스입니다.

// package com.example.eyedoc.Repo;
// import com.example.Model.Model__CheckAlready;
// 아래부터 복사해서 사용하세요

import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;

public interface RetrofitAPI {

    @POST("apiLink/info")
    Call<Model__CheckAlready> postOverlapCheck(@Body Model__CheckAlready modelCheckAlready); //이건 바디 요청시 사용하는거

    //@FormUrlEncoded
    //@POST("/auth/overlapChecker")
    //Call<Model__CheckAlready> postOverlapCheck(@Field("phone") String phoneNum, @Field("message") String message); //이건 요청시 사용하는거 (*데이터를 보낼때)
}

우선 포스트 방식만 설명합니다. 우선 api주소를 백엔드 개발자나 서버개발자분한테 받으면 보통 Get이나 Post로 접근하라고 설정해줄것입니다. 

 

여기서 받은 api세부 링크 주소를 넣어야하는데,

@POST("세부링크")

형식으로 주석을 달아주시면됩니다. 그리고 이 아래에

Call<Model__CheckAlready> postOverlapCheck(@Body Model__CheckAlready modelCheckAlready);

해당 문구를 넣으면됩니다. Call은 retrofit의 거시기같은데... 이를 통해 데이터를 쉽게 주고받을수있습니다. 여기서 Call<>에 들어갈 타입명은 추가할 api에 따른 데이터모델을 집어넣으면됩니다. 다음으로 이 데이터모델을 작성합니다.

 

*@POST에선

넘겨주는 인자에 보통 @Body로 자바클래스 객체를 넣어주게됩니다. 이 자바클래스 객체는 바로 이어서 알려드릴 클래스입니다. 그리고 @Field등등이 있습니다만 여기선 @Body 주석을 활용합니다.

 

 

 

 

 

 

 

7. Model__CheckAlready.class 를 추가해주세요.

= api 요청하고 이를 받을 데이터 모델을 의미하는 클래스입니다.

= 아래 클래스는 중복번호 체크에 활용하고 있었습니다.

//기존에 패키지주소까지 바꿔버리시면 안되요~!

import com.google.gson.annotations.SerializedName;

public class Model__CheckAlready {

//    {
//        "phone": "01012345678",
//        "message": "can use number"
//    }

    private boolean isRight = false;
    private String phone;
    private String message;

    public Model__CheckAlready(String phone) {
        this.phone = phone;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public boolean isRight() {
        return isRight;
    }

    public void setRight(boolean right) {
        isRight = right;
    }

    @Override
    public String toString() {
        return "RepoCheckAlready{" +
                "phone='" + phone + '\'' +
                ", message='" + message + '\'' +
                '}';
    }
}

복잡합니다! 중요한건 다시 아래만 아시면됩니다. 여기서 알아야할 부분은 바로 아래입니다.

//    {
//        "phone": "01012345678",
//        "message": "can use number"
//    }

// 위 json 파일형식을 api요청하여 받아온다면 이에 해당하는 변수를 대응시켜 만들어줘야함
    private String phone;
    private String message;

만약 api를 요청해서 받는 json데이터가 위 주석과 같은 형태라면 두 가지 데이터를 담을 변수가 필요합니다. 이를 만들어줘야합니다. 중요한점은 받을 key값의 이름 그대로 변수로 활용해야한다는겁니다. 그래야지 자동으로 api호출값을 받아옵니다. (예를들어 여기선 phone과 message임)

 

그리고 추가적으로 alt+insert 단축키를 활용하여 생성자와 getter setter를 설정해줍니다. 생성자는 필요에 맞게 받아올 인자를 정해주시면 됩니다. 여기선 생성자에 사용되는 인자는 phone이고, 폰번호 넘겨줘서 중복인지 아닌지 message를 받아옵니다.

 

 

 

 

 

 

8. CallRestrofit.class를 만들어주세요

= 지금까지 작성된 api Call을 실행하는 클래스입니다. 각 요청의 실행로직을 확인하기 위해서 따로 클래스를 만들었습니다. 앞서 RetrofitApi에 하나만 넣어줬기 때문에 여기서도 한개의 함수만 있습니다.

//모델 경로는 각자 다르므로 주석처리
//import com.example.Model__CheckAlready;

import android.util.Log;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class CallRetrofit {
    public boolean callPhoneAlreadyCheck(String phoneNumber){
        boolean isRight = false;

        //Retrofit 호출
        Model__CheckAlready modelCheckAlready = new Model__CheckAlready(phoneNumber);
        Call<Model__CheckAlready> call = RetrofitClient.getApiService().postOverlapCheck(modelCheckAlready);
        call.enqueue(new Callback<Model__CheckAlready>() {
            @Override
            public void onResponse(Call<Model__CheckAlready> call, Response<Model__CheckAlready> response) {
                if(!response.isSuccessful()){
                    Log.e("연결이 비정상적 : ", "error code : " + response.code());
                    return;
                }
                Model__CheckAlready checkAlready = response.body();
                Log.d("연결이 성공적 : ", response.body().toString());
                if(modelCheckAlready.getMessage() == "can use this number"){
                    Log.d("중복검사: ", "중복된 번호가 아닙니다");
                    modelCheckAlready.setRight(true);
                }
            }
            @Override
            public void onFailure(Call<Model__CheckAlready> call, Throwable t) {
                Log.e("연결실패", t.getMessage());
            }
        });

        return modelCheckAlready.isRight();
    }
}

저는 여기서 연결성공 여부에 따라 아에 boolean값을 받도록 설정해놓았습니다.

 

휴대폰번호를 인자로 넘겨받아 이를 앞서 생성한 Model__CheckAlready 의 생성자의 인자로 넣습니다. 그러면 이 데이터에 폰번호가 입력될 것이고, 이를 Retrofit의 Call에 넘겨서 해당 번호에 맞는 값을 가져올것입니다.

 

...

...

...

 

최대한 쉽게 작성해보고 싶었는데 그게 어렵네요. 어쨌든 대강 이런 구성으로 이루어져 있습니다. 오류가 있을수도 있을거같은데... 오류나는 부분은 수정해가며 사용하시면 더 이해하기 편할것같습니다. 사용하는것의 전체적인 이해에 조금이라도 도움이 되셨길 바랍니다!