본문 바로가기
안드로이드 자바

[Java][Android] retrofit2 사용법

by teamnova 2021. 3. 12.

오늘은 레트로핏2 라이브러리를 이용해서 서버와 통신하는 방법에 대해 알아보겠습니다. 

 

Gradle 의존성 추가

레트로핏2 라이브러리를 사용하기 위해 build.gradle(app) 파일에 retrofit 라이브러를 추가해줍니다. 

서버에서 보낸 응답 json 데이터를 변환하기 위해 Gson 변환기 라이브러리도 함께 추가해줍니다.

 

Manifest에 uses-permission 추가

네트워크 통신 시 필요한 권한을 매니페스트에 추가해줍니다. 

<uses-permission android:name="android.permission.INTERNET"/>

 

 

레이아웃 구현

activity_retrofit.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Retrofit">

    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="유저 id를 입력해주세요"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.297"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.833" />

    <Button
        android:id="@+id/btn_sendIdx"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="28dp"
        android:layout_marginLeft="28dp"
        android:text="전송"
        app:layout_constraintBottom_toBottomOf="@+id/editText"
        app:layout_constraintStart_toEndOf="@+id/editText"
        app:layout_constraintTop_toTopOf="@+id/editText"
        app:layout_constraintVertical_bias="0.0" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="152dp"
        android:text="title: "
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.07"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="48dp"
        android:text="body: "
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.072"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView2"
        app:layout_constraintVertical_bias="0.0" />

    <TextView
        android:id="@+id/title"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:text=""
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="@+id/textView2"
        app:layout_constraintStart_toEndOf="@+id/textView2"
        app:layout_constraintTop_toTopOf="@+id/textView2"
        app:layout_constraintVertical_bias="0.0" />

    <TextView
        android:id="@+id/body"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="12dp"
        android:layout_marginLeft="12dp"
        android:text=""
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="@+id/textView3"
        app:layout_constraintStart_toEndOf="@+id/textView3"
        app:layout_constraintTop_toTopOf="@+id/textView3"
        app:layout_constraintVertical_bias="0.0" />


</androidx.constraintlayout.widget.ConstraintLayout>

 

https://jsonplaceholder.typicode.com/post 로  id값을 보내면 id값에 해당하는 title과 body 내용을 받아서 보여주는 간단한 레이아웃입니다.

 

DTO 클래스 생성

DataClass.java

public class DataClass {

    // @SerializedName으로 일치시켜 주지않을 경우엔 클래스 변수명이 일치해야함
    @SerializedName("title")
    public String title;

    @SerializedName("body")
    public String body;


    // toString()을 Override 해주지 않으면 객체 주소값을 출력함
    @Override
    public String toString() {
        return "PostResult{" +
                "name=" + title +
                ", nickname=" + body + '\'' +
                '}';
    }
}

요청 url로부터 받아온 json 형식의 데이터를 변환하여 매핑할 DTO 클래스를 생성해줍니다.

 

Interface 정의

public interface RetrofitInterface {

    // @GET( EndPoint-자원위치(URI) )
    // DataClass > 요청 GET에 대한 응답데이터를 받아서 DTO 객체화할 클래스 타입 지정
    // getName > 메소드 명. 자유롭게 설정 가능, 통신에 영향x
    // @Path("post") String post > 매개변수. 매개변수 post가 @Path("post")를 보고 @GET 내부 {post}에 대입
    @GET("posts/{id}")  // 모든 유저의 id값만 받아오는 메서드(id 중복체크를 위해)
    Call<DataClass> getName(@Path("id") String post);

}

레트로핏 인터페이스를 정의하고 서버와 통신 시 사용할 메서드를 선언해줍니다.

 

서버 통신 로직 구현

RetrofitActivity.java

public class Retrofit extends AppCompatActivity {
    String TAG = "Retrofit";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_retrofit);

        //Retrofit 인스턴스 생성
        retrofit2.Retrofit retrofit = new retrofit2.Retrofit.Builder()
                .baseUrl("https://jsonplaceholder.typicode.com/")    // baseUrl 등록
                .addConverterFactory(GsonConverterFactory.create())  // Gson 변환기 등록
                .build();

        RetrofitInterface service = retrofit.create(RetrofitInterface.class);   // 레트로핏 인터페이스 객체 구현

        Button btn_sendIdx = findViewById(R.id.btn_sendIdx);    // 전송 버튼
        btn_sendIdx.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Log.e(TAG, "버튼 클릭");

                // edittext로부터 유저가 입력한 idx값을 가져온다
                EditText editText_idx = findViewById(R.id.editText);
                String idx = editText_idx.getText().toString(); // 서버로 보낼 idx

                Call<DataClass> call = service.getName(idx);

                call.enqueue(new Callback<DataClass>() {
                    @Override
                    public void onResponse(Call<DataClass> call, Response<DataClass> response) {
                        Log.e(TAG, "onResponse");
                        if(response.isSuccessful()){
                            Log.e(TAG, "onResponse success");
                            DataClass result = response.body();

                            // 서버에서 응답받은 데이터를 TextView에 넣어준다.
                            TextView name = findViewById(R.id.title);
                            TextView nickname = findViewById(R.id.body);

                            name.setText(result.title);
                            nickname.setText(result.body);

                        }
                        else{
                            // 실패
                            Log.e(TAG, "onResponse fail");
                        }
                    }

                    @Override
                    public void onFailure(Call<DataClass> call, Throwable t) {
                        // 통신 실패
                        Log.e(TAG, "onFailure: " + t.getMessage());
                    }
                });
            }
        });
    }
}

위의 로직을 통해 유저가 전송 버튼을 누르면 EditTextView에 입력한 id값을 서버로 보낸 후, 서버로부터 응답 결과를 받아서 title과 body를 TextView에 보여주게 됩니다.

저는 Retrofit 인스턴스 생성 시 스틱코드에 저장된 코드를 불러와서 좀 더 빠르게 구현해봤습니다. 

stickode.com/code.html?fileno=9578 

 

STICKODE - 코드 등록하기

스틱코드에서 개발에 필요한 전세계의 모든 코드들을 찾아보세요! Java, Android, Kotlin, PHP 등의 수 많은 언어와 플랫폼을 지원합니다.

stickode.com


완성 영상

앱을 실행하면 다음과 같은 모습을 볼 수 있습니다.