드레:
코딩 뿌시기
드레:
전체 방문자
오늘
어제
  • 분류 전체보기 (268)
    • Python (74)
      • Python 기초 (42)
      • Numpy (8)
      • Pandas (22)
    • Machine Learning (31)
      • Machine Learning (1)
      • Deep Learning (27)
    • AWS (22)
      • RDS (3)
      • EC2 (9)
      • Lambda (8)
      • S3 (2)
    • MySQL (24)
    • Git (8)
    • Streamlit (12)
    • REST API (22)
    • Java (24)
    • Android (36)
    • Debugging (15)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • JWT
  • Python
  • 네이버 API
  • pandas
  • rest api
  • tensorflow
  • GET
  • fine tuning
  • Transfer Learning
  • volley
  • CNN
  • 서버리스
  • 딥러닝
  • AWS Lambda
  • aws s3
  • EC2
  • Streamlit
  • flask
  • Lambda
  • Ann
  • Callback
  • Java
  • 안드로이드 스튜디오
  • API
  • 액션바
  • Retrofit2
  • 깃이그노어
  • AWS
  • github
  • serverless

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
드레:

코딩 뿌시기

Android Studio - Retrofit2를 이용해 API 서버에 요청하기(POST)
Android

Android Studio - Retrofit2를 이용해 API 서버에 요청하기(POST)

2023. 2. 9. 22:28

1. Retrofit2 라이브러리

  • HTTP 통신 라이브러리 중 Volley와 함께 가장 많이 사용되는 대표적인 라이브러리
  • 동일 Squareup사의 OkHttp 라이브러리의 상위 구현체
    - Retrofit은 OkHttp를 네트워크 계층으로 활용하고 그 위에 구축 됨
  • Volley는 response로 받은 JSON 파싱을 직접 해줘야 해서 코딩이 길어지는 반면,
    Retrofit은 자동으로 파싱을 해줘서 더 간단하게 사용할 수 있다.

 

 

2. Retrofit2 사용을 위한 설정

 

인터넷 사용 권한 설정

  • AndroidManifest.xml에 추가해준다.
  • 안드로이드 에뮬레이터에서 인터넷을 사용하기 위한 설정은 이 포스팅을 참고
<uses-permission android:name="android.permission.INTERNET" />

 

dependencies 추가

  • build.gradle(Module)에 추가해준다.
dependencies {
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation("com.squareup.okhttp3:logging-interceptor:4.9.0")
}

 

 

Retrofit 객체를 생성하는 함수

  • 복사 붙여넣기로 사용할 템플릿
  • 유지보수를 위해 api 패키지를 만들어 그 안에 작성한다.
import android.content.Context;

import com.reodinas2.memoapp.config.Config;

import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class NetworkClient {

    public static Retrofit retrofit;

    public static Retrofit getRetrofitClient(Context context){
        if (retrofit == null){
            // 통신 로그 확인할 때 필요한 코드
            HttpLoggingInterceptor loggingInterceptor =
                    new HttpLoggingInterceptor();
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); // 커스터마이징 할 부분(로그레벨)

            // 네트워크 연결 관련 코드
            OkHttpClient httpClient = new OkHttpClient.Builder()
                    .connectTimeout(1, TimeUnit.MINUTES)
                    .readTimeout(1, TimeUnit.MINUTES)
                    .writeTimeout(1, TimeUnit.MINUTES)
                    .addInterceptor(loggingInterceptor)
                    .build();

            // 네트워크로 데이터를 보내고 받는
            // 레트로핏 라이브러리 관련 코드
            retrofit = new Retrofit.Builder()
                    .baseUrl(Config.DOMAIN)  // 커스터마이징 할 부분(요청 도메인)
                    .client(httpClient)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

        }
        return retrofit;

    }
}

 

 

 

3. API 명세서를 보고 모델, 인터페이스 만들기

 

아래와 같이 요청하고 응답받는 회원가입 처리를 하는 API 서버에 요청할 것이다.

 

3-1. Request 할 때 데이터를 담아서 보낼 클래스를 만든다.

  • 유지보수를 위해 model 패키지를 만들어 그 안에 작성한다.
import java.io.Serializable;

// 레트로핏 라이브러리를 통해서, Body에 Json으로 데이터를 보낼 클래스
// 1. Serializable 해준다.
// 2. API 명세서를 보고, 멤버변수를 만든다(이름 같게).
// 3. 멤버변수를 private 해준다.
// 4. Getter/Setter 만들어준다.
public class User implements Serializable {
    private String email;
    private String password;
    private String nickname;


    public User() {
    }


    public User(String email, String password, String nickname) {
        this.email = email;
        this.password = password;
        this.nickname = nickname;
    }


    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
}

 

3-2. Response 받을 때 데이터를 담아서 전달 받을 클래스를 만든다.

  • 유지보수를 위해 model 패키지를 만들어 그 안에 작성한다.
import java.io.Serializable;

//레트로핏 라이브러리를 통해서 응답받는 클래스
public class UserRes implements Serializable {
    private String result;
    private String access_token;


    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public String getAccess_token() {
        return access_token;
    }

    public void setAccess_token(String access_token) {
        this.access_token = access_token;
    }
}

 

 

3-3. Retrofit이 처리할 수 있도록 API 인터페이스를 만든다.

  • 유지보수를 위해 api 패키지를 만들어 그 안에 작성한다.
import com.reodinas2.memoapp.model.User;
import com.reodinas2.memoapp.model.UserRes;

import retrofit2.Call;
import retrofit2.http.Body;

// 유저 관련 API 들을 모아놓은 인터페이스
public interface UserApi {

    // 회원가입 API 함수 작성
    @POST("/user/register")
    Call<UserRes> register(@Body User user);

 

 

 

4. Retrofit을 사용해 API 서버에 요청, 응답

// 회원가입 API를 호출!
// 1. 다이얼로그를 화면에 보여준다.
showProgress("회원가입 중입니다");

// 2. 서버로 데이터를 보낸다.
// 2-1. 레트로핏 변수 생성
Retrofit retrofit = NetworkClient.getRetrofitClient(RegisterActivity.this);

// 2-2. api 패키지에 있는 인터페이스 생성
UserApi api = retrofit.create(UserApi.class);

// 2-3. 보낼 데이터 만들기 => 클래스의 객체 생성
User user = new User(email, password, nickname);

// 2-4. api 호출
Call<UserRes> call = api.register(user);
// 2-5. 서버로부터 받아온 응답을 처리하는 코드 작성
call.enqueue(new Callback<UserRes>() {
    @Override
    public void onResponse(Call<UserRes> call, Response<UserRes> response) {
        // 프로그레스 다이얼로그가 있으면, 나타나지 않게 해준다.
        dismissProgress();

        // 서버에서 보낸 응답이 200 OK 일 때 처리하는 코드
        if (response.isSuccessful()) {
            Log.i("MEMO_APP", response.toString());

            // 서버가 보낸 데이터를 받는 방법!!!
            UserRes res = response.body();

            Log.i("MEMO_APP", res.getResult());
            Log.i("MEMO_APP", res.getAccess_token());

            // 억세스토큰은, api 할 때마다 헤더에서 사용하므로
            // 회원가입이나 로그인이 끝나면, 파일로 꼭 저장해 놔야 한다.
            SharedPreferences sp =
                    getApplication().getSharedPreferences(Config.SP_NAME, MODE_PRIVATE);
            SharedPreferences.Editor editor = sp.edit();
            editor.putString(Config.ACCESS_TOKEN, res.getAccess_token());
            editor.apply();

            // 3. 데이터를 이상없이 처리하면,
            //    메인액티비티를 화면에 나오게 한다.
            Intent intent = new Intent(RegisterActivity.this, MainActivity.class);
            startActivity(intent);
            finish();

        }else{
            Log.i("MEMO_APP", response.toString());
        }

    }

    @Override
    public void onFailure(Call<UserRes> call, Throwable t) {
        // 프로그레스 다이얼로그가 있으면, 나타나지 않게 해준다.
        dismissProgress();

    }
});

 

 

 

5. 전체 코드

 

RegisterActivity.java

package com.reodinas2.memoapp;

import androidx.appcompat.app.AppCompatActivity;

import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.reodinas2.memoapp.api.NetworkClient;
import com.reodinas2.memoapp.api.UserApi;
import com.reodinas2.memoapp.config.Config;
import com.reodinas2.memoapp.model.User;
import com.reodinas2.memoapp.model.UserRes;

import java.util.regex.Pattern;

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

public class RegisterActivity extends AppCompatActivity {

    EditText editEmail;
    EditText editPassword;
    EditText editNickname;
    Button btnRegister;
    TextView txtLogin;

    // 네트워크를 통해서 로직처리를 할 때 보여주는
    // 프로그레스 다이얼로그
    ProgressDialog dialog;


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

        editEmail = findViewById(R.id.editEmail);
        editPassword = findViewById(R.id.editPassword);
        editNickname = findViewById(R.id.editNickname);
        btnRegister = findViewById(R.id.btnLogin);
        txtLogin = findViewById(R.id.txtRegister);

        btnRegister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                // 이메일 가져와서 형식 체크
                String email = editEmail.getText().toString().trim();

                Pattern pattern = Patterns.EMAIL_ADDRESS;

                if(!pattern.matcher(email).matches()){
                    Toast.makeText(RegisterActivity.this, "이메일 형식이 올바르지 않습니다.", Toast.LENGTH_SHORT).show();
                    editEmail.requestFocus();
                    return;
                }

                // 비밀번호 체크
                String password = editPassword.getText().toString().trim();
                // 비밀번호 길이 4~12만 허용
                if(password.length() < 4 || password.length() > 12){
                    Toast.makeText(RegisterActivity.this, "비밀번호는 4자이상, 12자 이하여야 합니다.", Toast.LENGTH_SHORT).show();
                    editPassword.requestFocus();
                    return;
                }

                // 닉네임 가져온다.
                String nickname = editNickname.getText().toString().trim();
                if(nickname.isEmpty()){
                    Toast.makeText(RegisterActivity.this, "닉네임은 필수항목입니다.", Toast.LENGTH_SHORT).show();
                    editNickname.requestFocus();
                    return;
                }

                // 회원가입 API를 호출!
                // 1. 다이얼로그를 화면에 보여준다.
                showProgress("회원가입 중입니다");

                // 2. 서버로 데이터를 보낸다.
                // 2-1. 레트로핏 변수 생성
                Retrofit retrofit = NetworkClient.getRetrofitClient(RegisterActivity.this);

                // 2-2. api 패키지에 있는 인터페이스 생성
                UserApi api = retrofit.create(UserApi.class);

                // 2-3. 보낼 데이터 만들기 => 클래스의 객체 생성
                User user = new User(email, password, nickname);

                // 2-4. api 호출
                Call<UserRes> call = api.register(user);
                // 2-5. 서버로부터 받아온 응답을 처리하는 코드 작성
                call.enqueue(new Callback<UserRes>() {
                    @Override
                    public void onResponse(Call<UserRes> call, Response<UserRes> response) {
                        // 프로그레스 다이얼로그가 있으면, 나타나지 않게 해준다.
                        dismissProgress();

                        // 서버에서 보낸 응답이 200 OK 일 때 처리하는 코드
                        if (response.isSuccessful()) {
                            Log.i("MEMO_APP", response.toString());

                            // 서버가 보낸 데이터를 받는 방법!!!
                            UserRes res = response.body();

                            Log.i("MEMO_APP", res.getResult());
                            Log.i("MEMO_APP", res.getAccess_token());

                            // 억세스토큰은, api 할 때마다 헤더에서 사용하므로
                            // 회원가입이나 로그인이 끝나면, 파일로 꼭 저장해 놔야 한다.
                            SharedPreferences sp =
                                    getApplication().getSharedPreferences(Config.SP_NAME, MODE_PRIVATE);
                            SharedPreferences.Editor editor = sp.edit();
                            editor.putString(Config.ACCESS_TOKEN, res.getAccess_token());
                            editor.apply();

                            // 3. 데이터를 이상없이 처리하면,
                            //    메인액티비티를 화면에 나오게 한다.
                            Intent intent = new Intent(RegisterActivity.this, MainActivity.class);
                            startActivity(intent);
                            finish();

                        }else{
                            Log.i("MEMO_APP", response.toString());
                        }

                    }

                    @Override
                    public void onFailure(Call<UserRes> call, Throwable t) {
                        // 프로그레스 다이얼로그가 있으면, 나타나지 않게 해준다.
                        dismissProgress();

                    }
                });

            }
        });

        txtLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
                startActivity(intent);
                finish();
            }
        });

    }

    // 네트워크 로직 처리시에 화면에 보여주는 함수
    void showProgress(String message){
        dialog = new ProgressDialog(this);
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setMessage(message);
        dialog.show();
    }


    // 로직처리가 끝나면 화면에서 사라지는 함수
    void dismissProgress(){
        dialog.dismiss();
    }

}

 

 

activity_register.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=".RegisterActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:gravity="center"
            android:text="회원가입"
            android:textSize="28sp" />

        <EditText
            android:id="@+id/editEmail"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:ems="10"
            android:hint="이메일"
            android:inputType="textEmailAddress"
            android:textSize="28sp" />

        <EditText
            android:id="@+id/editPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="비밀번호"
            android:inputType="textPassword"
            android:textSize="28sp" />

        <EditText
            android:id="@+id/editNickname"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="닉네임"
            android:inputType="textPersonName"
            android:textSize="28sp" />

        <Button
            android:id="@+id/btnLogin"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="50dp"
            android:text="회원가입"
            android:textSize="28sp" />

        <TextView
            android:id="@+id/txtRegister"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:gravity="center"
            android:text="@string/txt_login_btn"
            android:textColor="#6167D3"
            android:textSize="26sp" />
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

 

'Android' 카테고리의 다른 글

Android Studio - DatePickerDialog/TimePickerDialog 사용법  (0) 2023.02.17
Android Studio - Retrofit2를 이용해 API 서버에 요청하기(GET) + RecyclerVeiw 에 표시  (0) 2023.02.13
Android Studio - Volley 라이브러리 Body와 Header에 데이터 담아서 Request 하는 법  (0) 2023.02.08
Android Studio - RecyclerView 페이징 처리 (마지막까지 스크롤 됐을 때, 이벤트 처리)  (0) 2023.02.08
Android Studio - Intent 활용 (주소록, 웹, SMS, Email 열기)  (0) 2023.02.07
    'Android' 카테고리의 다른 글
    • Android Studio - DatePickerDialog/TimePickerDialog 사용법
    • Android Studio - Retrofit2를 이용해 API 서버에 요청하기(GET) + RecyclerVeiw 에 표시
    • Android Studio - Volley 라이브러리 Body와 Header에 데이터 담아서 Request 하는 법
    • Android Studio - RecyclerView 페이징 처리 (마지막까지 스크롤 됐을 때, 이벤트 처리)
    드레:
    드레:

    티스토리툴바