본문 바로가기
Android Studio

[Android Studio] Android Studio + Spring Boot + mariaDB ( 회원가입 ) (2)

by jisayDeveloper 2023. 11. 6.
728x90
반응형

설정이 끝났으니 회원가입 예제를 만들어 봅니다.

 

activity_main.xml

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

    <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/frame"/>

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_alignParentBottom="true">
            
        <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
                android:id="@+id/btn_1"
                android:layout_weight="1"
                android:layout_margin="1dp"
                android:text="로그인"/>
                
        <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
                android:id="@+id/btn_2"
                android:layout_weight="1"
                android:layout_margin="1dp"
                android:text="회원가입"/>
                
        <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
                android:id="@+id/btn_3"
                android:layout_weight="1"
                android:layout_margin="1dp"
                android:text="홈"/>
                
        <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
                android:id="@+id/btn_4"
                android:layout_weight="1"
                android:layout_margin="1dp"
                android:text="마이페이지"/>


    </LinearLayout>
</RelativeLayout>

 

fragment2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              android:padding="16dp">

    <EditText
            android:id="@+id/userId"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="아이디"
            android:layout_margin="16dp" />

    <EditText
            android:id="@+id/userPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="비밀번호"
            android:password="true"
            android:layout_margin="16dp" />

    <EditText
            android:id="@+id/checkPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="비밀번호 확인"
            android:password="true"
            android:layout_margin="16dp" />

    <TextView
            android:id="@+id/textCheck"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textColor="#FF0000"
            android:text="비밀번호를 입력하세요"/>

    <EditText
            android:id="@+id/userName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="이름"
            android:layout_margin="16dp" />

    <EditText
            android:id="@+id/userBirth"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="생년월일"
            android:layout_margin="16dp" />

    <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="회원가입"
            android:id="@+id/buttonRegister" />
</LinearLayout>

<TextView>를 통해 비밀번호가 맞는 지 검사하고 맞으면 '일치합니다.' 아니면 '일치하지 않습니다.'를 출력합니다.

 

ApiService

package com.example.fragmenexample;

import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;

public interface ApiService {
    @POST("/user/join")
    Call<UserDTO> joinUser(@Body RequestBody body);

}

회원가입을 위해 @Body를 사용해서 '/user/jonin'으로 post 요청을 보냅니다.

 

UserDTO

package com.example.fragmenexample;

public class UserDTO {

    String id;
    String password;
    String name;
    String birth;

    public UserDTO(String id, String password, String name, String birth) {
        this.id = id;
        this.password = password;
        this.name = name;
        this.birth = birth;
    }
}

 

Fragment2

코드가 길어서 끊어서 쓰겠습니다.

private Button buttonRegister;
private EditText userId, userPassword, userBirth, userName, checkPassword;
private TextView textCheck;
private ApiService apiService;

필요한 객체들 선언합니다.

 

    public Fragment2(){

    }

    @Nullable
    @org.jetbrains.annotations.Nullable
    @Override
    public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment2, container, false);
        
        userBirth = (EditText) view.findViewById(R.id.userBirth);
        userId = (EditText) view.findViewById(R.id.userId);
        userName = (EditText) view.findViewById(R.id.userName);
        userPassword = (EditText) view.findViewById(R.id.userPassword);
        checkPassword = (EditText)view.findViewById(R.id.checkPassword);
        textCheck = (TextView) view.findViewById(R.id.textCheck);

저번 코드에서 return을 위 코드처럼 바꿔줍니다. 그리고 요소들을 연결합니다.

 

checkPassword.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                if (userPassword.getText().toString().equals(checkPassword.getText().toString())) {
                    textCheck.setText("일치합니다.");
                    textCheck.setTextColor(Color.BLUE);
                } else {
                    textCheck.setText("일치하지 않습니다.");
                    textCheck.setTextColor(Color.RED);
                }
            }

        });

비밀번호 확인에  TextWatcher를 사용해서 비밀번호 일치 여부를 확인하고 TextView에 출력합니다.

 

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://10.0.2.2:8080")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        apiService = retrofit.create(ApiService.class);

        buttonRegister = view.findViewById(R.id.buttonRegister);

        buttonRegister.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if(checkPassword.getText().toString().equals(userPassword.getText().toString())) {
                    registerUser();
                }else {
                    textCheck.setText("일치하지 않습니다.");
                    textCheck.setTextColor(Color.RED);
                    Toast.makeText(getContext(), "비밀번호 확인 요망", Toast.LENGTH_SHORT).show();
                }
            }
        });

        return view;
    }

Retrofit 객체를 만들 때 baseUrl 부분 조심해야하는데

 

로컬 서버를 사용할 때 localhost나 127.0.0.1을 쓰면 Exception 나옵니다.

10.0.2.2은 에뮬레이터 로컬 서버 접속으로 이걸 적거나 본인 pc IP주소를 넣어야 제대로 실행합니다.

 

private void registerUser() {
        String id = userId.getText().toString().trim();
        String password = userPassword.getText().toString().trim();
        String name = userName.getText().toString().trim();
        String birth = userBirth.getText().toString().trim();

        UserDTO user = new UserDTO(id, password, name, birth);

        //UserDTO 객체를 JSON 문자열로 변환
        Gson gson = new Gson();
        String json = gson.toJson(user);

        //JSON 문자열을 RequestBody 객체로 만듭니다.
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), json);
  
        Call<UserDTO> call = apiService.joinUser(requestBody);

        call.enqueue(new Callback<UserDTO>() {
            @Override
            public void onResponse(Call<UserDTO> call, Response<UserDTO> response) {
                if (response.isSuccessful()) {
                    // 회원가입 성공 시 처리
                    UserDTO registeredUser = response.body();
                    Toast.makeText(getContext(), "회원가입 성공", Toast.LENGTH_SHORT).show();
                } else {
                    // 서버에서 실패 상태 코드 반환 시
                    Toast.makeText(getContext(), "회원가입 실패", Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onFailure(Call<UserDTO> call, Throwable t) {
                // 네트워크 오류 또는 예외 처리
                Log.e("Network Error", t.getMessage());
                Toast.makeText(getContext(), "네트워크 오류", Toast.LENGTH_SHORT).show();
            }
        });

    }

 

서버에서 RequestBody로 바인딩 하긴 때문에 json으로 꼭 변환해야하고 성공과 실패에 따라 토스트가 나오면서 회원가입이 이루어집니다.

 

전체코드는

package com.example.fragmenexample;

import android.graphics.Color;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.google.gson.Gson;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

import java.io.IOException;

public class Fragment2 extends Fragment {

    private Button buttonRegister;
    private EditText userId, userPassword, userBirth, userName, checkPassword;
    private TextView textCheck;
    private ApiService apiService;

    public Fragment2(){

    }

    @Nullable
    @org.jetbrains.annotations.Nullable
    @Override
    public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment2, container, false);

        userBirth = (EditText) view.findViewById(R.id.userBirth);
        userId = (EditText) view.findViewById(R.id.userId);
        userName = (EditText) view.findViewById(R.id.userName);
        userPassword = (EditText) view.findViewById(R.id.userPassword);
        checkPassword = (EditText)view.findViewById(R.id.checkPassword);
        textCheck = (TextView) view.findViewById(R.id.textCheck);

        checkPassword.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                if (userPassword.getText().toString().equals(checkPassword.getText().toString())) {
                    textCheck.setText("일치합니다.");
                    textCheck.setTextColor(Color.BLUE);
                } else {
                    textCheck.setText("일치하지 않습니다.");
                    textCheck.setTextColor(Color.RED);
                }
            }

        });


        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://10.0.2.2:8080")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        apiService = retrofit.create(ApiService.class);

        buttonRegister = view.findViewById(R.id.buttonRegister); // 버튼 초기화

        buttonRegister.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if(checkPassword.getText().toString().equals(userPassword.getText().toString())) {
                    registerUser();
                }else {
                    textCheck.setText("일치하지 않습니다.");
                    textCheck.setTextColor(Color.RED);
                    Toast.makeText(getContext(), "비밀번호 확인 요망", Toast.LENGTH_SHORT).show();
                }
            }
        });

        return view;
    }

    private void registerUser() {
        String id = userId.getText().toString().trim();
        String password = userPassword.getText().toString().trim();
        String name = userName.getText().toString().trim();
        String birth = userBirth.getText().toString().trim();

        UserDTO user = new UserDTO(id, password, name, birth);

        //UserDTO 객체를 JSON 문자열로 변환
        Gson gson = new Gson();
        String json = gson.toJson(user);

        //JSON 문자열을 RequestBody 객체로 만듭니다.
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), json);

        Log.d("RequestBody", json);


        Call<UserDTO> call = apiService.joinUser(requestBody);

        call.enqueue(new Callback<UserDTO>() {
            @Override
            public void onResponse(Call<UserDTO> call, Response<UserDTO> response) {
                if (response.isSuccessful()) {
                    // 회원가입 성공 시 처리
                    UserDTO registeredUser = response.body();
                    Toast.makeText(getContext(), "회원가입 성공", Toast.LENGTH_SHORT).show();
                } else {
                    // 서버에서 실패 상태 코드 반환 시
                    Toast.makeText(getContext(), "회원가입 실패", Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onFailure(Call<UserDTO> call, Throwable t) {
                // 네트워크 오류 또는 예외 처리
                Log.e("Network Error", t.getMessage());
                Toast.makeText(getContext(), "네트워크 오류", Toast.LENGTH_SHORT).show();
            }
        });

    }
}

 

결과를 보겠습니다.

 

 

 

 

db에 잘 들어간 걸 볼 수 있습니다.

 

 

 

 

 

 

 

728x90
반응형