๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“STUDY/๐Ÿ“šAndroidStudio

[์•ˆ๋“œ๋กœ์ด๋“œ์ŠคํŠœ๋””์˜ค] 10. ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ ์š”์ฒญํ•˜๊ณ  ์‘๋‹ต๋ฐ›๊ธฐ

by Yun Je 2020. 5. 22.

1. ๋„คํŠธ์›Œํ‚น์ด๋ž€?

๋„คํŠธ์›Œํ‚น์€ ์ธํ„ฐ๋„ท์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ์›๊ฒฉ์ง€์˜ ์„œ๋ฒ„ ๋˜๋Š” ์›๊ฒฉ์ง€์˜ ๋‹จ๋ง๊ณผ ํ†ต์‹ ํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ๋™์ž‘๋“ค์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์ด์šฉํ•˜๋ฉด ๋‹จ๋ง์˜ ๋ฐ์ดํ„ฐ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ฉ€๋ฆฌ ๋–จ์–ด์ ธ ์žˆ๋Š” ์„œ๋ฒ„๋‚˜ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์˜ ๋‹จ๋ง์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋•Œ

(1) ๋จผ์ € ์ธํ„ฐ๋„ท์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ํ†ต์‹ ์ด ๊ฐ€๋Šฅํ•œ์ง€๋ฅผ ์•Œ์•„๋ณธ ํ›„ (2) ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ๊ณผ์ •์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. 

 

๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ๊ณผ์ •์€ ์ƒ๋‹นํžˆ ๋ณต์žกํ•˜์ง€๋งŒ, ์ธํ„ฐ๋„ท์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ์—ฌ๋Ÿฌ ๋‹จ๋ง์„ ๋™์‹œ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์„œ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ์ž์›์„ ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ๋ฐฉ์‹ ์ดํ•ดํ•˜๊ธฐ

  • '2-tier C/S(Client/Server)' ์—ฐ๊ฒฐ ๋ฐฉ์‹

2-tier C/S ์—ฐ๊ฒฐ ๋ฐฉ์‹

2-tier C/S ์—ฐ๊ฒฐ ๋ฐฉ์‹์€ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋„คํŠธ์›Œํ‚น ๋ฐฉ์‹์œผ๋กœ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ€ ์ผ๋Œ€์ผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. 

๋Œ€๋ถ€๋ถ„ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์— ์—ฐ๊ฒฐ๋˜์–ด ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๊ณ  ์‘๋‹ต๋ฐ›๋Š” ๋‹จ์ˆœํ•œ ๊ฐœ๋…์œผ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

  ์˜ˆ) ์›น ํŽ˜์ด์ง€๋ฅผ ๋ณผ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” HTTP ํ”„๋กœํ† ์ฝœ, ํŒŒ์ผ ์ „์†ก์„ ์œ„ํ•œ TFP ํ”„๋กœํ† ์ฝœ, ๋ฉ”์ผ์„ ์ฃผ๊ณ ๋ฐ›๋Š” POP3 ํ”„๋กœํ† ์ฝœ

 

  • 3-tier ์—ฐ๊ฒฐ ๋ฐฉ์‹

3-tier ์—ฐ๊ฒฐ๋ฐฉ์‹

3-tier ์—ฐ๊ฒฐ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์‘์šฉ ์„œ๋ฒ„์™€ ๋ฐ์ดํ„ฐ ์„œ๋ฒ„๋กœ ๋‚˜๋ˆ„์–ด ์„œ๋ฒ„๋ฅผ ๊ตฌ์„ฑํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ์ค‘๊ฐ„์— ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง(Business Logic)์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์‘์šฉ ์„œ๋ฒ„๊ฐ€ ์ข€ ๋” ๋‹ค์–‘ํ•œ ์—ญํ• ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. 

 

๋‹จ๋ง ๊ฐ„์˜ ํ†ต์‹ ์ด ์ผ๋ฐ˜ํ™”๋˜๋ฉฐ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„์˜ ๊ด€๊ณ„๋Š” peer-to-peer ํ†ต์‹ ์œผ๋กœ ๋ถˆ๋ฆฌ๋Š” P2P ๋ชจ๋ธ๋กœ ๋ณ€ํ˜•๋˜์–ด ์‚ฌ์šฉ๋˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. 

 

  • P2P ๋ชจ๋ธ

P2P ๋ฐฉ์‹๊ณผ ์„œ๋ฒ„ ์—ฐ๊ฒฐ ๋ฐฉ์‹์˜ ๋น„๊ต

์„œ๋ฒ„๋ฅผ ๋‘์ง€ ์•Š๊ณ  ๋‹จ๋ง๋ผ๋ฆฌ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. 

  ์˜ˆ) ์ •๋ณด ๊ฒ€์ƒ‰, ํŒŒ์ผ ์†ก์ˆ˜์‹ 

 

๋ฉ”์‹ ์ € ์„œ๋น„์Šค, ์ธํ„ฐ๋„ท ์ „ํ™”์— ์‚ฌ์šฉ๋˜๋Š” SIP ํ”„๋กœํ† ์ฝœ ๊ธฐ๋ฐ˜์˜ ์„œ๋น„์Šค๋“ค์€ ์„œ๋ฒ„๊ฐ€ ์กด์žฌํ•˜์ง€๋งŒ P2P ๋ชจ๋ธ์˜ ํŠน์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 

 

2. ์†Œ์ผ“ ์‚ฌ์šฉํ•˜๊ธฐ

IP์ฃผ์†Œ๋กœ ๋ชฉ์ ์ง€ ํ˜ธ์ŠคํŠธ๋ฅผ ์ฐพ์•„๋‚ด๊ณ  ํฌํŠธ๋กœ ํ†ต์‹  ์ ‘์†์ ์„ ์ฐพ์•„๋‚ด๋Š” ์†Œ์ผ“ ์—ฐ๊ฒฐ์€ TCP์™€ UDP ๋ฐฉ์‹์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋Š” ๋Œ€๋ถ€๋ถ„ TCP ์—ฐ๊ฒฐ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. 

 

HTTP ํ”„๋กœํ† ์ฝœ๊ณผ ์†Œ์ผ“

HTTP ํ”„๋กœํ† ์ฝœ์€ ์›น์„œ๋ฒ„์— ์—ฐ๊ฒฐํ•œ ํ›„์— ์š”์ฒญ์„ ์ „์†กํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ›์€ ๋‹ค์Œ ์—ฐ๊ฒฐ์„ ๋Š์Šต๋‹ˆ๋‹ค. - ๋น„์—ฐ๊ฒฐ์„ฑ(Stateless)

 

์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์•ฑ์€ ์‘๋‹ต์†๋„๋ฅผ ๋†’์ด๊ธฐ ์œ„ํ•ด ์—ฐ๊ฒฐ์„ฑ์ด ์žˆ๋Š” ์†Œ์ผ“ ์—ฐ๊ฒฐ์„ ์„ ํ˜ธํ–ˆ์Šต๋‹ˆ๋‹ค. 

์ง€๊ธˆ์€ ์ธํ„ฐ๋„ท์˜ ์†๋„๊ฐ€ ๋นจ๋ผ์ ธ HTTP ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๋Š” ์›น์ด ์ผ๋ฐ˜์ ์ด ๋˜์—ˆ๊ณ  ๊ฒฐ๊ตญ ์†๋„๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ๋А๋ฆฌ์ง€ ์•Š์œผ๋ฉด์„œ๋„ ๊ตญ์ œ ํ‘œ์ค€์„ ๋”ฐ๋ฅผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์„ ๊ฐ€์ง„ ์›น์„œ๋ฒ„๋กœ ๋งŽ์€ ์„œ๋ฒ„๊ฐ€ ๋งŒ๋“ค์–ด์ง€๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. 

 

์•ˆ๋“œ๋กœ์ด๋“œ๋Š” ํ‘œ์ค€ ์ž๋ฐ”์—์„œ ์‚ฌ์šฉํ•˜๋˜ java.net ํŒจํ‚ค์ง€์˜ ํด๋ž˜์Šค๋“ค์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜์—ฌ ์†Œ์ผ“ ์—ฐ๊ฒฐ์„ ์•„์ฃผ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

๋‹จ, ์•ˆ๋“œ๋กœ์ด๋“œ๋Š” ์†Œ์ผ“ ์—ฐ๊ฒฐ ๋“ฑ์„ ์‹œ๋„ํ•˜๊ฑฐ๋‚˜ ์‘๋‹ต์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•  ๋•Œ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

(์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ๋„คํŠธ์›Œํ‚น ๊ธฐ๋Šฅ ์ž์ฒด๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. )

 

๋„คํŠธ์›Œํ‚น ์‹ค์Šต - ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ์†Œ์ผ“ ๋งŒ๋“ค๊ธฐ (SampleSocket Project)

๋”๋ณด๊ธฐ

[์กฐ๊ฑด]

 - ์ตœ์ƒ์œ„ ๋ ˆ์ด์•„์›ƒ์€ LinearLayout, orientation ์†์„ฑ ๊ฐ’์€ vertical

 - ๋ฉ”์ธ ํ™”๋ฉด์˜ ์œ„ ์ชฝ์€ ํด๋ผ์ด์–ธํŠธ ์˜์—ญ, ์•„๋ž˜ ์ชฝ์€ ์„œ๋ฒ„ ์˜์—ญ

 - ๋ฆฌ๋‹ˆ์–ด ๋ ˆ์ด์•„์›ƒ์„ ๋‘ ๊ฐœ ์ถ”๊ฐ€ํ•˜๊ณ  ์œ„์ชฝ ๊ณต๊ฐ„๊ณผ ์•„๋ž˜์ชฝ ๊ณต๊ฐ„ ๋‚˜๋ˆ„์–ด ๊ฐ€์ง

     -> layout_height ์†์„ฑ ๊ฐ’์€ 0dp, layout_weight ์†์„ฑ ๊ฐ’์€ 1dp๋กœ ์„ค์ •

 - ์œ„์ชฝ ๋ ˆ์ด์•„์›ƒ์—๋Š” ์ž…๋ ฅ ์ƒ์ž์™€ ๋ฒ„ํŠผ ํ•˜๋‚˜์”ฉ ์ถ”๊ฐ€, ์Šคํฌ๋กค๋ทฐ์— ํฌํ•จ๋œ ํ…์ŠคํŠธ๋ทฐ ๋ฐฐ์น˜

 - ์•„๋ž˜์ชฝ ๋ ˆ์ด์•„์›ƒ์—๋Š” ๋ฒ„ํŠผ ํ•˜๋‚˜, ์Šคํฌ๋กค๋ทฐ์— ํฌํ•จ๋œ ํ…์ŠคํŠธ๋ทฐ ๋ฐฐ์น˜

 - ์œ„์ชฝ ๋ ˆ์ด์•„์›ƒ์˜ ๋ฒ„ํŠผ์€ '์ „์†ก', ์•„๋ž˜์ชฝ ๋ ˆ์ด์•„์›ƒ์˜ ๋ฒ„ํŠผ์€ '์„œ๋ฒ„ ์‹œ์ž‘'

 - ์œ„์ชฝ ๋ ˆ์ด์•„์›ƒ์˜ ์ƒ‰์€ ๋ฐ์€ ํŒŒ๋ž‘, ์•„๋ž˜์ชฝ ๋ ˆ์ด์•„์›ƒ์˜ ์ƒ‰์€ ์˜ค๋žœ์ง€์ƒ‰์œผ๋กœ ์„ค์ •

 

[activity_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"
    android:weightSum="2"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#0099ff"
        android:orientation="vertical">

        <EditText
            android:id="@+id/editText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="textPersonName"
            android:text="" />

        <Button
            android:id="@+id/button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="์ „์†ก" />

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical" >

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#ffcc66"
        android:orientation="vertical">
        <Button
            android:id="@+id/button2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="์„œ๋ฒ„ ์‹œ์ž‘" />

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical" >

                <TextView
                    android:id="@+id/textView2"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="" />
            </LinearLayout>
        </ScrollView>
    </LinearLayout>
</LinearLayout>

 

[ํ™”๋ฉด ๋ ˆ์ด์•„์›ƒ]

 

[MainActivity.java]

package org.techtown.socket;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.util.Log;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.InetAddress;

public class MainActivity extends AppCompatActivity {
    EditText editText;

    TextView textView;
    TextView textView2;

    Handler handler = new Handler();


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

        editText = findViewById(R.id.editText);
        textView = findViewById(R.id.textView);
        textView2 = findViewById(R.id.textView2);

        Button button= findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                final String data = editText.getText().toString();
                new Thread(new Runnable(){
                    @Override
                    public void run(){
                        send(data);
                    }
                }).start();
            }
        });

        Button button2 = findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                new Thread(new Runnable(){
                    @Override
                    public void run(){
                        startServer();
                    }
                }).start();
            }
        });
    }

    public void printClientLog(final String data){
        Log.d("MainActivity", data);    //import android.util.Log
        handler.post(new Runnable(){
            @Override
            public void run(){
                textView.append(data+"\n");
            }
        });
    }
    public void printServerLog(final String data){
        Log.d("MainActivity", data);

        handler.post(new Runnable(){
            @Override
            public void run(){
                textView2.append(data + "\n");
            }
        });
    }

    public void send(String data){
        try{
            int portNumber = 5001;
            Socket sock = new Socket("localhost", portNumber);
            printClientLog("์†Œ์ผ“ ์—ฐ๊ฒฐํ•จ. ");

            ObjectOutputStream outstream = new ObjectOutputStream(sock.getOutputStream());
            outstream.writeObject(data);
            outstream.flush();
            printClientLog("๋ฐ์ดํ„ฐ ์ „์†กํ•จ. ");

            ObjectInputStream instream = new ObjectInputStream(sock.getInputStream());
            printClientLog("์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์Œ: " + instream.readObject());
            sock.close();
        } catch(Exception ex){
            ex.printStackTrace();
        }
    }

    public void startServer(){
        try{
            int portNumber = 5001;

            ServerSocket server = new ServerSocket(portNumber);
            printServerLog("์„œ๋ฒ„ ์‹œ์ž‘ํ•จ: " + portNumber);

            while(true){
                Socket sock = server.accept();
                InetAddress clientHost = sock.getLocalAddress();
                int clientPort = sock.getPort();
                printServerLog("ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ๋จ: " + clientHost + " : " + clientPort);

                ObjectInputStream instream = new ObjectInputStream(sock.getInputStream());
                Object obj = instream.readObject();
                printServerLog("๋ฐ์ดํ„ฐ ๋ฐ›์Œ: " + obj);

                ObjectOutputStream outstream = new ObjectOutputStream(sock.getOutputStream());
                outstream.writeObject(obj + " from Server. ");
                outstream.flush();
                printServerLog("๋ฐ์ดํ„ฐ ๋ณด๋ƒ„. ");

                sock.close();
            }
        } catch(Exception ex){
            ex.printStackTrace();
        }
    }
}

[์‹คํ–‰ ๊ฒฐ๊ณผ]

์•ฑ์„ ์‹คํ–‰ํ•˜๊ณ  '์„œ๋ฒ„ ์‹œ์ž‘' ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์„œ๋ฒ„๊ฐ€ ์‹œ์ž‘๋˜์—ˆ๋‹ค๋Š” ๋กœ๊ทธ๊ฐ€ ํ™”๋ฉด ํ•˜๋‹จ์— ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. 

ํ™”๋ฉด ์ƒ๋‹จ์— ์žˆ๋Š” ์ž…๋ ฅ์ƒ์ž์— ๊ธ€์ž๋ฅผ ์ž…๋ ฅํ•˜๊ณ  '์ „์†ก'์„ ๋ˆ„๋ฅด๋ฉด ๊ทธ ๊ธ€์ž๊ฐ€ ์„œ๋ฒ„๋กœ ์ „์†ก๋˜์—ˆ๋‹ค๊ฐ€ ๋‹ค์‹œ ํด๋ผ์ด์–ธํŠธ์ชฝ์œผ๋กœ ์ „๋‹ฌ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

3. ์›น์œผ๋กœ ์š”์ฒญํ•˜๊ธฐ

์ผ๋ฐ˜์ ์ธ HTTP ํ”„๋กœํ† ์ฝœ์€ ๋น„์—ฐ๊ฒฐ์„ฑ(Stateless)์ด๋ฏ€๋กœ ํŽ˜์ด์ง€ ์ •๋ณด๋ฅผ ์š”์ฒญํ•  ๋•Œ๋งˆ๋‹ค ์†Œ์ผ“์„ ์ƒˆ๋กœ ์—ฐ๊ฒฐํ•˜๊ณ , ์‘๋‹ต์„ ๋ฐ›์€ ํ›„์—๋Š” ์†Œ์ผ“์˜ ์—ฐ๊ฒฐ์„ ๋Š์Šต๋‹ˆ๋‹ค. 

์†Œ์ผ“์ด ์—ฐ๊ฒฐ ๋˜์—ˆ์„ ๋•Œ ํ•ด๋‹น ์—ฐ๊ฒฐ์—์„œ HTTP์— ๋งž๋Š” ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์‘๋‹ต์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. 

 

HTTP๋กœ ์›น ์„œ๋ฒ„์— ์ ‘์†ํ•˜๊ธฐ

HTTP๋กœ ์›น ์„œ๋ฒ„์— ์ ‘์†ํ•˜๋Š” ๊ฒƒ๋„ ํ‘œ์ค€ ์ž๋ฐ”์˜ ๋ฐฉ์‹์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

์ž๋ฐ”์—์„œ HTTP ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€

(1) URL ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  (2) ์ด ๊ฐ์ฒด์˜ openConnection() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ (3) HttpURLConnection ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. 

 

URL ๊ฐ์ฒด์— ๋“ค์–ด ์žˆ๋Š” ๋ฌธ์ž์—ด์ด "http://"๋ฅผ ํฌํ•จํ•˜๋ฉด HTTP ์—ฐ๊ฒฐ์„ ์œ„ํ•œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜๋ฏ€๋กœ Connection() ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฆฌํ„ดํ•˜๋Š” URLConnection ๊ฐ์ฒด๋ฅผ HttpURLConnection์œผ๋กœ ํ˜•๋ณ€ํ™˜ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

HttpURLConnection ๊ฐ์ฒด๋กœ ์—ฐ๊ฒฐํ•  ๊ฒฝ์šฐ GET๊ณผ POST์™€ ๊ฐ™์€ ์š”์ฒญ ๋ฐฉ์‹๊ณผ ํ•จ๊ป˜ ์š”์ฒญ์„ ์œ„ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

์š”์ฒญ ๋ฐฉ์‹์„ ์ง€์ •ํ•˜๋Š” ๋ฉ”์„œ๋“œ

  • public void setRequestMethod(String method)
  • public void setRequestProperty(String field, Stirng newValue)

setRequestMethod() : GET์ด๋‚˜ POST ๋ฌธ์ž์—ด์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ

setRequestPriority() : ์š”์ฒญ ์‹œ ํ—ค๋”์— ๋“ค์–ด๊ฐ€๋Š” ํ•„๋“œ ๊ฐ’ ์ง€์ •

 

GET ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์›นํŽ˜์ด์ง€ ์ฃผ์†Œ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ํ•ด๋‹น ํŽ˜์ด์ง€์˜ ๋‚ด์šฉ ๊ฐ€์ ธ์˜ค๊ธฐ (SampleHttp)

๋”๋ณด๊ธฐ

[์กฐ๊ฑด]

 - ์ตœ์ƒ์œ„ ๋ ˆ์ด์•„์›ƒ์€ ๋ฆฌ๋‹ˆ์–ด ๋ ˆ์ด์•„์›ƒ, oorientation ์†์„ฑ ๊ฐ’์€ vertical

 - ์ž…๋ ฅ์ƒ์ž, ๋ฒ„ํŠผ์„ ๋„ฃ๊ณ  ์Šคํฌ๋กค ๋ทฐ๋ฅผ ์ถ”๊ฐ€ํ•œ ํ›„ ํ…์ŠคํŠธ ๋ทฐ ์ถ”๊ฐ€

 - ์ž…๋ ฅ์ƒ์ž์— ์‚ฌ์ดํŠธ ์ฃผ์†Œ ์ž…๋ ฅ, ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๊ทธ ์‚ฌ์ดํŠธ๋กœ๋ถ€ํ„ฐ ์‘๋‹ต ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ์•„๋ž˜ ์ชฝ์˜ ํ…์ŠคํŠธ ๋ทฐ์— ๋ณด์—ฌ์คŒ

 - ๋ฒ„ํŠผ์€ '์š”์ฒญํ•˜๊ธฐ' ๊ธ€์ž๊ฐ€ ๋ณด์ด๊ฒŒ ํ•˜๊ณ , ์ž…๋ ฅ์ƒ์ž์—๋Š” '์‚ฌ์ดํŠธ ์ฃผ์†Œ ์ž…๋ ฅ'์ด๋ผ๋Š” ๊ธ€์ž๊ฐ€ ์•ˆ๋‚ด๊ธ€๋กœ ๋‚˜ํƒ€๋‚˜๋„๋ก hint์†์„ฑ ์„ค์ •

 

[activity_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"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="์‚ฌ์ดํŠธ ์ฃผ์†Œ ์ž…๋ ฅ"
        android:inputType="textPersonName" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="์š”์ฒญํ•˜๊ธฐ" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

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

</LinearLayout>

 

[ํ™”๋ฉด ๋ ˆ์ด์•„์›ƒ]

 

[MainActivity.java]

package org.techtown.http;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import static java.sql.DriverManager.println;

public class MainActivity extends AppCompatActivity {
    EditText editText;
    TextView textView;

    Handler handler = new Handler();

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

        editText = findViewById(R.id.editText);
        textView = findViewById(R.id.textView);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                final String urlStr = editText.getText().toString();
                new Thread(new Runnable(){
                    @Override
                    public void run(){
                        request(urlStr);
                    }
                }).start();
            }
        });
        /*
        ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ์‚ฌ์ดํŠธ ์ฃผ์†Œ ์ด์šฉํ•ด request() ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
        request() ๋ฉ”์„œ๋“œ์—์„œ ์ธํ„ฐ๋„ท์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์Šค๋ ˆ๋“œ ์•ˆ์—์„œ ๋™์ž‘ํ•˜๋„๋ก ํ•จ
         -> ์Šค๋ ˆ๋“œ ๊ฐ์ฒด ์ƒ์„ฑํ•˜๊ณ  ๊ทธ ์•ˆ์—์„œ request() ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
         ์Šค๋ ˆ๋“œ์—์„œ ์ฒ˜๋ฆฌํ•œ ๊ฒฐ๊ณผ๋ฌผ์„ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๋„๋ก ํ•ธ๋“ค๋Ÿฌ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ๋ณ€์ˆ˜์— ํ• ๋‹น
         */
    }
    public void request(String urlStr){ //์‘๋‹ต ๊ฒฐ๊ณผ๋ฌผ์„ ๋ชจ์•„ ํ™”๋ฉด์— ์ถœ๋ ฅ
        StringBuilder output = new StringBuilder();
        try{
            URL url = new URL(urlStr);

            HttpURLConnection conn = (HttpURLConnection)url.openConnection();   //HttpURLConnection ๊ฐ์ฒด๋งŒ๋“ค๊ธฐ
            if(conn != null) {
                conn.setConnectTimeout(10000);  //10์ดˆ๊ฐ„ ์—ฐ๊ฒฐ ๋Œ€๊ธฐ
                conn.setRequestMethod("GET");
                conn.setDoInput(true);  //๊ฐ์ฒด์— ์ž…๋ ฅ ๊ฐ€๋Šฅ

                int resCode = conn.getResponseCode();   //๋‚ด๋ถ€์ ์œผ๋กœ ์›น ์„œ๋ฒ„์— ํŽ˜์ด์ง€ ์š”์ฒญ(GET ๋ฐฉ์‹)
                BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); //์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๊ธฐ ์œ„ํ•œ Reader๊ฐ์ฒด ์ƒ์„ฑ
                String line = null;
                while (true) {
                    line = reader.readLine();
                    if (line == null) {
                        break;
                    }

                    output.append(line + "\n");
                }
                reader.close();
                conn.disconnect();
            }
        } catch (Exception ex){
            println("์˜ˆ์™ธ ๋ฐœ์ƒํ•จ: "+ ex.toString());
        }
        println("์‘๋‹ต-> " + output.toString());
    }

    public void println(final String data) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                textView.append(data + "\n");
            }
        });
    }
}

 

[app>manifests>AndroidManifet.xml]

์ธํ„ฐ๋„ท ๊ถŒํ•œ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ manifest ํŒŒ์ผ์— ๊ถŒํ•œ ์ถ”๊ฐ€

 -> application ํƒœ๊ทธ์— android:userCleartextTraffic="true"

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.techtown.http">

    <application
        android:usesCleartextTraffic="true"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

 

[์‹คํ–‰ ๊ฒฐ๊ณผ]

 ์ž…๋ ฅ ์ƒ์ž์—

http://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=430156241533f1d058c603178cc3ca0e&targetDt=20120101

 ์œ„์˜ ์ฃผ์†Œ ์ž…๋ ฅ ํ›„ ์š”์ฒญํ•˜๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด

์—๋Ÿฌ๋กœ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š๋Š”๋‹ค. (ํ•ด๊ฒฐ : ์ธํ„ฐ๋„ท ์ ‘๊ทผ ๊ถŒํ•œ ์„ค์ • (manifestํŒŒ์ผ) + printlnํ•จ์ˆ˜ handler ๊ฐ์ฒด ์ด์šฉํ•ด ์žฌ์ •์˜)

์ž…๋ ฅํ•œ ์ฃผ์†Œ๋Š” ์˜ํ™” ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ์˜คํ”ˆ๋˜์–ด์žˆ๋Š” ์ฃผ์†Œ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์ฃผ์†Œ ์•ˆ์˜ key๊ฐ’์€ ์ง์ ‘ ์‚ฌ์ดํŠธ์— ๋“ฑ๋กํ•˜์—ฌ ๋ฐœ๊ธ‰๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

์‘๋‹ต ๊ฒฐ๊ณผ๋ฌผ์˜ ํฌ๋ฉง์€ JSON ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค. 

 

4. Volley ์‚ฌ์šฉํ•˜๊ธฐ

์›น์„œ๋ฒ„์— ์š”์ฒญํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ›์„ ๋•Œ HttpURLConnection ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ,

์š”์ฒญ๊ณผ ์‘๋‹ต์— ํ•„์š”ํ•œ ์ฝ”๋“œ์˜ ์–‘์ด ๋งŽ๊ณ , ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋„ฃ์–ด์•ผ ํ•˜๋Š” ์ฝ”๋“œ์˜ ์–‘๋„ ๋งŽ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ํ•ธ๋“ค๋Ÿฌ์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ์—†๋‹ค๋ฉด ์•ฑ์ด ๋น„์ •์ƒ ์ข…๋ฃŒ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ Volley์ž…๋‹ˆ๋‹ค. 

Volley ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์›น ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ๋‹จ์ˆœํ™” ํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž…๋‹ˆ๋‹ค. 

 

Volley๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด

๋จผ์ € (1) ์š”์ฒญ(Request) ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  (2) ์ด ์š”์ฒญ ๊ฐ์ฒด๋ฅผ ์š”์ฒญ ํ(RequestQueue)์— ๋„ฃ์–ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์š”์ฒญ ํ๊ฐ€ ์•Œ์•„์„œ ์›น์„œ๋ฒ„์— ์š”์ฒญํ•˜๊ณ  ์‘๋‹ต๊นŒ์ง€ ๋ฐ›์•„์ค๋‹ˆ๋‹ค. 

์ด ์‘๋‹ต์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ์ง€์ •๋œ ๋ฉ”์Šค๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋‘๊ธฐ๋งŒ ํ•˜๋ฉด ์‘๋‹ต์ด ์™”์„ ๋•Œ ๋ฉ”์„œ๋“œ๊ฐ€ ์ž๋™ ํ˜ธ์ถœ ๋ฉ๋‹ˆ๋‹ค. 

Volley๋ฅผ ์ด์šฉํ•œ ์š”์ฒญ๊ณผ ์‘๋‹ต ์ฒ˜๋ฆฌ

Volley ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•˜๋ฉด ์Šค๋ ˆ๋“œ๋ฅผ ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค. 

์š”์ฒญ ํ์˜ ๋‚ด๋ถ€์—์„œ ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค์–ด ์›น ์„œ๋ฒ„์— ์š”์ฒญํ•˜๊ณ  ์‘๋‹ต๋ฐ›๋Š” ๊ณผ์ •์„ ์ง„ํ–‰ํ•˜๊ณ , ์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋Š” ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. 

๋”ฐ๋ผ์„œ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†๊ณ  ํ™”๋ฉด์— ๊ฒฐ๊ณผ๋ฅผ ํ‘œ์‹œํ•  ๋•Œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๋„ ์—†์Šต๋‹ˆ๋‹ค. 

 

Volley ์‚ฌ์šฉํ•ด์„œ ์›น ์š”์ฒญ๊ณผ ์‘๋‹ต ์ฒ˜๋ฆฌํ•˜๊ธฐ (SampleRequest)

๋”๋ณด๊ธฐ

[์กฐ๊ฑด]

 - Volley ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€ : Volley๋Š” ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฏ€๋กœ build.gradle ํŒŒ์ผ์— ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•จ

   -> /app/Gradle Scripts ํด๋” ์•ˆ์˜ build.gradle(Module:app) ํŒŒ์ผ์„ ์—ด๊ณ  dependencies ์ค‘๊ด„ํ˜ธ ์•ˆ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  [Sync Now] ๋งํฌ๋ฅผ ํด๋ฆญ ํ•˜๋ฉด ์ž๋™์œผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€

 implementation 'com.android.volley:volley:1.1.0'

 - manifests์˜ application ํƒœ๊ทธ์— usesCleartextTraffic ์†์„ฑ ์ถ”๊ฐ€

 - SampleHttp์™€ ๊ฐ™์€ ๋ ˆ์ด์•„์›ƒ ์‚ฌ์šฉ

 

[volley ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€]

 

[Internet ๊ถŒํ•œ ์ถ”๊ฐ€]

 

[MainActivity.java]

package org.techtown.request;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import java.util.HashMap;
import java.util.Map;

import static java.sql.DriverManager.println;

public class MainActivity extends AppCompatActivity {
    EditText editText;
    TextView textView;

    static RequestQueue requestQueue;   //์š”์ฒญ ํ๋Š” ํ•œ ๋ฒˆ๋งŒ ๋งŒ๋“ค์–ด ๊ณ„์† ์‚ฌ์šฉ : static

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

        editText = findViewById(R.id.editText);
        textView = findViewById(R.id.textView);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                makeRequest();
            }
        });
        if(requestQueue==null){
            requestQueue = Volley.newRequestQueue(getApplicationContext());
        }
    }
    public void makeRequest(){
        String url = editText.getText().toString();

        StringRequest request = new StringRequest(Request.Method.GET, url,
                new Response.Listener<String>(){
            @Override
                    public void onResponse(String response){
                println("์‘๋‹ต-> " + response);
            }
                },
        new Response.ErrorListener(){
            public void onErrorResponse(VolleyError error){
                println("์—๋Ÿฌ-> " + error.getMessage());
            }
        }
        ){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();

                return params;
            }
        };
        request.setShouldCache(false);
        requestQueue.add(request);
        println("์š”์ฒญ ๋ณด๋ƒ„.");
    }

    public void println(String data){
        textView.append(data + "\n");
    }
}

 

 [์‹คํ–‰ ๊ฒฐ๊ณผ]

์Šค๋ ˆ๋“œ๋‚˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ์›น ์‚ฌ์ดํŠธ ์š”์ฒญ, ์‘๋‹ต์ด ๋ฌธ์ œ์—†์ด ์ง„ํ–‰๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

5. JSON ๋ฐ์ดํ„ฐ ๋‹ค๋ฃจ๊ธฐ

JSON์˜ ์•ฝ์ž๋Š” JavaScript Object Notation์œผ๋กœ ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด ํฌ๋งท์„ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฌธ์ž์—ด๋กœ ํ‘œํ˜„ํ•œ ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค. 

์†์„ฑ์˜ ์ด๋ฆ„๊ณผ ๋ฌธ์ž์—ด์— ํฐ๋”ฐ์˜ดํ‘œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์ •๋„์˜ ์ฐจ์ด๋ฅผ ์ œ์™ธํ•˜๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด ํฌ๋งท๊ณผ ๊ฑฐ์˜ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. 

 

JSON์€ ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด ํฌ๋งท์ด๋ฏ€๋กœ ์ค‘๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ค‘๊ด„ํ˜ธ ์•ˆ์— ์ฝค๋งˆ(,)๋กœ ๊ฐ ์†์„ฑ๊ฐ’๋“ค์„ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๊ณ , ๊ฐ๊ฐ์˜ ์†์„ฑ ์ž์ฒด๋Š” ์†์„ฑ ์ด๋ฆ„๊ณผ ์†์„ฑ ๊ฐ’์ด ์ฝœ๋ก (:) ๊ธฐํ˜ธ๋กœ ๊ตฌ๋ถ„๋˜๋ฉด์„œ ํ•œ ์Œ์„ ์ด๋ฃน๋‹ˆ๋‹ค. 

์ฝœ๋ก  ๋’ค์— ๋“ค์–ด๊ฐ€๋Š” ๊ฐ’์€ ๋ฌธ์ž์—ด์ด๋‚˜ ์ˆซ์ž์™€ ๊ฐ™์€ ๊ธฐ๋ณธ ์ž๋ฃŒํ˜•์ด๋‚˜ ์ค‘๊ด„ํ˜ธ๋กœ ์‹ธ์ธ ๊ฐ์ฒด๊ฐ€ ์˜ฌ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. 

๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋Œ€๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์›์†Œ๋“ค์„ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. 

 

์›น ์‘๋‹ต์œผ๋กœ ๋ฐ›์€ JSON ๊ฒฐ๊ณผ๋ฌผ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ• : Gson

 

Gson์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ์ฒ˜๋Ÿผ JSON ๋ฌธ์ž์—ด์„ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, JSON ๋ฌธ์ž์—ด์ด ์ž๋ฐ” ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

Volley๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์›น ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ JSON์‘๋‹ต์„ ๋ฐ›์•˜๋”ฐ๋ฉด Gson์„ ์ด์šฉํ•ด ์ž๋ฐ” ๊ฐ์ฒด๋กœ ๋ฐ”๊พธ๊ณ , ๊ทธ ๊ฐ์ฒด ์•ˆ์— ๋“ค์–ด์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ ‘๊ทผํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. 

Gson์˜ ์—ญํ• 

Gson๋„ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋จผ์ € ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

Gson์œผ๋กœ ์‘๋‹ต ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ (SampleRequest2)

 

๋Œ“๊ธ€