gradle
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")
}
UserApi (인터페이스)
package com.leopard4.memoapp.api;
import com.leopard4.memoapp.model.User;
import com.leopard4.memoapp.model.UserRes;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;
// 유저 관련 API 들을 모아놓은 인터페이스
public interface UserApi {
// 회원가입 API 함수 작성
@POST("/user/register") // API 명세서에 있는 경로를 작성한다.
Call<UserRes> register(@Body User user); // Body 에 Json 으로 데이터를 보낸다. // Call<UserRes> 는 응답을 받을 클래스를 지정한다.
// 로그인 API 함수 작성
@POST("/user/login")// @의 의미는 레트로핏 라이브러리가 이 함수를 레트로핏 API 로 사용한다는 의미이다.
Call<UserRes> login(@Body User user);
}
MemoApi (인터페이스)
package com.leopard4.memoapp.api;
import com.leopard4.memoapp.model.MemoList;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Query;
public interface MemoApi {
// 내 메모 가져오는 API
@GET("/memos")
Call<MemoList> getMemoList(@Header("Authorization") String token, @Query("offset") int offset, @Query("limit") int limit);
}
Config
package com.leopard4.memoapp.config;
public class Config {
// 서버 주소
public static final String DOMAIN = "개인적인 엔드포인트주소";
public static final String DOMAIN_TEST = "http://localhost:5000";
public static final String PREFERENCE_NAME = "memo_app";
public static final String ACCESS_TOKEN = "access_token";
}
NetworkClient
package com.leopard4.memoapp.api;
import android.content.Context;
import com.leopard4.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); // 실배포시는 NONE으로 설정 (해킹문제)
// 네트워크 연결관련 코드
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;
}
}
user모델
package com.leopard4.memoapp.model;
import java.io.Serializable;
public class User implements Serializable {
// 레트로핏 라이브러리를 통해서, Body 에 Json으로 데이터를 보낼 클래스
// 1. Serializable 인터페이스를 구현한다.
// 2. API 명세서를 보고, 멤버변수를 만든다.
// 3. 멤버변수는 private 으로 선언한다.
// 4. 멤버변수에 대한 Getter, Setter 를 만든다.
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 User(String email, String password) {
this.email = email;
this.password = password;
}
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;
}
}
UserRes
package com.leopard4.memoapp.model;
import java.io.Serializable;
// 레트로핏 라이브러리를 통해서 응답받는 클래스
public class UserRes implements Serializable {
private String access_token;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
}
RegisterActivity
package com.leopard4.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.leopard4.memoapp.api.NetworkClient;
import com.leopard4.memoapp.api.UserApi;
import com.leopard4.memoapp.config.Config;
import com.leopard4.memoapp.model.User;
import com.leopard4.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() == false){
Toast.makeText(RegisterActivity.this, "이메일 형식이 올바르지 않습니다.", Toast.LENGTH_SHORT).show();
return;
}
// 비밀번호 체크
String password = editPassword.getText().toString().trim();
// 우리 기획에는 비번길이가 4~12 만 허용
if(password.length() < 4 || password.length() > 12){
Toast.makeText(RegisterActivity.this, "비번 길이를 확인하세요.", Toast.LENGTH_SHORT).show();
return;
}
// 닉네임 가져온다.
String nickname = editNickname.getText().toString().trim();
if(nickname.isEmpty()){
Toast.makeText(RegisterActivity.this, "닉네임은 필수입니다.", Toast.LENGTH_SHORT).show();
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.getAccess_token());
// 억세스토큰은, api 할때마다 헤더에서 사용하므로
// 회원가입이나 로그인이 끝나면, 파일로 꼭 저장해 놔야 한다.
SharedPreferences sp =
getApplication().getSharedPreferences(Config.PREFERENCE_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 v) {
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();
}
}
loginActivity
package com.leopard4.memoapp;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
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.leopard4.memoapp.api.NetworkClient;
import com.leopard4.memoapp.api.UserApi;
import com.leopard4.memoapp.config.Config;
import com.leopard4.memoapp.model.User;
import com.leopard4.memoapp.model.UserRes;
import java.util.regex.Pattern;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
public class LoginActivity extends AppCompatActivity {
EditText editEmail;
EditText editPassword;
Button btnLogin;
TextView txtRegister;
ProgressDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
editEmail = findViewById(R.id.editEmail);
editPassword = findViewById(R.id.editPassword);
btnLogin = findViewById(R.id.btnLogin);
txtRegister = findViewById(R.id.txtRegister);
btnLogin.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() == false){
Toast.makeText(LoginActivity.this, "이메일 형식이 올바르지 않습니다.", Toast.LENGTH_SHORT).show();
return;
}
String password = editPassword.getText().toString().trim();
// 우리 기획에는 비번길이가 4~12 만 허용
if(password.length() < 4 || password.length() > 12){
Toast.makeText(LoginActivity.this, "비번 길이를 확인하세요.", Toast.LENGTH_SHORT).show();
return;
}
showProgress("로그인 중입니다.");
Retrofit retrofit = NetworkClient.getRetrofitClient(LoginActivity.this);
UserApi api = retrofit.create(UserApi.class);
User user = new User(email, password);
Call<UserRes> call = api.login(user);
call.enqueue(new Callback<UserRes>() {
@Override
public void onResponse(Call<UserRes> call, Response<UserRes> response) {
dismissProgress();
if(response.isSuccessful() == false){
UserRes res = response.body();
SharedPreferences sp =
getApplication().getSharedPreferences(Config.PREFERENCE_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString(Config.ACCESS_TOKEN, res.getAccess_token() );
editor.apply();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
} else if (response.code() == 400) {
Toast.makeText(LoginActivity.this, "회원가입이 되어있지 않거나 비번이 틀렸습니다.", Toast.LENGTH_SHORT).show();
return;
} else {
Toast.makeText(LoginActivity.this, "정상적으로 처리되지 않았습니다.", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<UserRes> call, Throwable t) {
dismissProgress();
Toast.makeText(LoginActivity.this, "정상적으로 처리되지 않았습니다.", Toast.LENGTH_SHORT).show();
}
});
}
});
txtRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(LoginActivity.this, RegisterActivity.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();
}
}
memoList
package com.leopard4.memoapp.model;
import java.io.Serializable;
import java.util.List;
public class MemoList implements Serializable {
private String result;
private List<Memo> items;
private int count;
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public List<Memo> getItems() {
return items;
}
public void setItems(List<Memo> items) {
this.items = items;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
memo
package com.leopard4.memoapp.model;
import java.io.Serializable;
public class Memo implements Serializable {
private int id;
private String title;
private String datetime;
private String content;
private String createdAt;
private String updatedAt;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDatetime() {
return datetime;
}
public void setDatetime(String datetime) {
this.datetime = datetime;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public String getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(String updatedAt) {
this.updatedAt = updatedAt;
}
}
memoApi
package com.leopard4.memoapp.api;
import com.leopard4.memoapp.model.MemoList;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Query;
public interface MemoApi {
// 내 메모 가져오는 API
@GET("/memos")
Call<MemoList> getMemoList(@Header("Authorization") String token, @Query("offset") int offset, @Query("limit") int limit);
}
'Android' 카테고리의 다른 글
Android [파파고번역앱] 라디오 버튼, Volley (0) | 2023.02.13 |
---|---|
Android [AWS람다 메모앱] Retrofit2를 이용한 프론트엔드 CRUD, 로그인,회원가입,메인리사이클뷰,메모생성,조회,수정,삭제 (0) | 2023.02.10 |
Android [유튜브API동영상리스트불러오는앱] 페이징처리, url파싱, 카드뷰 선택시 웹브라우저 실행 (0) | 2023.02.08 |
Android 유튜브 API 썸네일 이미지를 안드로이드에서 열어보기 (0) | 2023.02.07 |
Android [공유인텐트] (0) | 2023.02.07 |