본문 바로가기
개발

Local에서 Express서버 구동 및 안드로이드 Retrofit 통신예제

by Jihunc 2022. 11. 5.

Express 서버를 local 에서 작성 및 구동하고 안드로이드 앱에서 서버의 정보를 가져오는 간단한 예제이다.

다음과 같은 순으로 진행하겠다.

 

  1. Node.js 다운로드, Express 라이브러리 다운로드 및 작업폴더 초기화
  2. 간단한 서버 코드 작성 및 구동 확인
  3. 안드로이드 Retrofit 코드 작성 (https://taewooblog.tistory.com/177 를 참고하였다.)
  4. 자잘한 설정
  5. 구동 확인
  6. 오류 해결

1. Node.js 다운로드 및 Express 라이브러리 설치

https://nodejs.org/ko/ 에 들어가서 노드를 설치한다.

LTS가 안정적이다.

노드 설치가 잘 되었는지 확인하기 위해서는 터미널에 아래와 같이 친다.

node -v

위와 같이 버전이 나오면 설치가 잘 된것이다

이후 작업할 폴더를 만들고 들어가서 작업환경을 초기화하고, express 라이브러리를 다운받는다.

npm init -y
npm install express

또, 서버파일을 수정할 때 마다 껏다 키기 귀찮으니 nodemon을 설치하여 적용이 실시간으로 되도록 하자.

npm install nodemon

설치 이후 작업 폴더의 "package.json" 파일에 아래와 같이 "script" 항목에 "server" : "nodemon server.js" 한 줄을 추가하도록 하자. 빠른 실행을 위한 스크립트 추가이다.

{
  "name": "server_test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "server": "nodemon server.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2",
    "mysql": "^2.18.1",
    "nodemon": "^2.0.20"
  }
}

2. 서버 코드 작성 및 구동 확인

이제 간단한 서버를 만들고 구동시켜보겠다. 아래와 같이 코드를 작성한다. 몇 줄만 작성하면 서버가 생긴다. 파일이름은 위의 package.json에서 server.js로 정했기 때문에 server.js로 해야한다.

const express = require('express');
const app = express();

app.listen(8080, function() {
    console.log('listening on 8080')
});

app.get("/info/30/", (req, res, next) => {
    res.json({age: 36, name: `Messi`, city: `Paris`, number: `30`});
});

코드를 작성하고 나서 서버를 실행한다.

npm run server

서버가 잘 돌아가는지 확인해보도록 하자. postman을 설치하면 API 요청을 확인해 볼 때 유용하다.

https://www.postman.com/downloads/ postman을 활용하여 내 서버로 들어가보자.

서버 주소는 https://localhost:8080/info/30 또는 https://127.0.0.1:8080/info/3 이다.

작성한 대로 잘 나와주는 것을 볼 수 있다. postman 뿐만 아니라, 일반 브라우저에서도 다 볼 수 있다.
이제 서버가 잘 돌아가는 것을 확인했으니, 안드로이드 앱에서 retrofit으로 서버의 정보를 가져와보자

3. 안드로이드 Retrofit코드 작성

우선 그레이들에 retrofit과 gson을 추가하고 싱크를 맞추자

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

retrofit통신을 하기 위해서는 3개의 파일이 필요하다. 서버의 정보를 가져올 데이터 타입을 정의한 클래스 파일, retrofit 객체 정의 클래스, 계속 api를 추가해 나갈 인터페이스이다.

우선 main.xml에 결과를 표시할 텍스트뷰 한 개를 추가한다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".MainActivity"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="QWE"/>

</LinearLayout>

아래의 클래스 파일들을 추가한다.

Datamodel.java

package com.kookmin.nodetest;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class DataModel {

    @SerializedName("age")
    @Expose
    private int age;

    @SerializedName("name")
    @Expose
    private String name;

    @SerializedName("city")
    @Expose
    private String city;

    @SerializedName("number")
    @Expose
    private String number;

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public String getCity() {
        return city;
    }

    public String getNumber() {
        return number;
    }
}

RetrofitClient.java

package com.kookmin.nodetest;

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://10.0.2.2:8080/";


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

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

RetrofitInterface.java

package com.kookmin.nodetest;

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;

public interface RetrofitInterface {

    @GET("info/{UserId}")
    Call<DataModel> test_my_server(
            @Path("UserId") String userid);
}

이렇게 Retrofit 코드 작성은 끝이다.

4. 자잘한 설정

안드로이드 앱이 인터넷 통신을 할 수 있도록 manifest.xml 파일에 인터넷 권한과, https 보안 접속 없이, http로 접속할 수 있게 해주는 코드를 추가한다.

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

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

5. 구동 확인

서버를 돌리고, 안드로이드 앱을 실행하면 서버파일에서 작성한 내용이 안드로이드 앱에서도 잘 출력이 되는것을 확인할 수 있다.

5. 오류 해결

1. CLEARTEXT communication to 10.0.2.2 not permitted by network security policy

위의 4. 자잘한 설정에서

android:usesCleartextTraffic="true"

이 항목을 추가하지 않아서 그렇다. https 보안 통신이 아니면 안드로이드에서 막는다. 하지만 우리는 http 통신을 써야하기 때문에 위 항목을 추가해야한다.

 

2. Failed to connect to localhost/127.0.0.1:8080

RetrofitClient.java 파일에서 BASE_URL을 제대로 설정하지 않았기 때문이다. 서버와 클라이언트 모두 같은 컴퓨터에서 진행하고, 안드로이드 앱에서 localhost를 확인하기 위해서는 주소가 다르기 때문이다.

안드로이드의 에뮬레이터의 localhost는 10.0.2.2:포트번호 이다.