1. ๋คํธ์ํน์ด๋?
๋คํธ์ํน์ ์ธํฐ๋ท์ ์ฐ๊ฒฐ๋์ด ์๋ ์๊ฒฉ์ง์ ์๋ฒ ๋๋ ์๊ฒฉ์ง์ ๋จ๋ง๊ณผ ํต์ ํด์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ๋์๋ค์ ํฌํจํฉ๋๋ค. ์ด๋ฅผ ์ด์ฉํ๋ฉด ๋จ๋ง์ ๋ฐ์ดํฐ๋ฟ๋ง ์๋๋ผ ๋ฉ๋ฆฌ ๋จ์ด์ ธ ์๋ ์๋ฒ๋ ๋ค๋ฅธ ์ฌ๋์ ๋จ๋ง์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ์๋ ์์ต๋๋ค.
์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๋
(1) ๋จผ์ ์ธํฐ๋ท์ ํตํด ๋ฐ์ดํฐ ํต์ ์ด ๊ฐ๋ฅํ์ง๋ฅผ ์์๋ณธ ํ (2) ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ๊ณผ์ ์ ์คํํฉ๋๋ค.
๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ๊ณผ์ ์ ์๋นํ ๋ณต์กํ์ง๋ง, ์ธํฐ๋ท์ ์ฐ๊ฒฐ๋์ด ์๋ ์ฌ๋ฌ ๋จ๋ง์ ๋์์ ์ฌ์ฉํ ์ ์์ด์ ๋ค์ํ ๋ฐ์ดํฐ ์์์ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋คํธ์ํฌ ์ฐ๊ฒฐ๋ฐฉ์ ์ดํดํ๊ธฐ
- '2-tier C/S(Client/Server)' ์ฐ๊ฒฐ ๋ฐฉ์
2-tier C/S ์ฐ๊ฒฐ ๋ฐฉ์์ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ ๋คํธ์ํน ๋ฐฉ์์ผ๋ก ํด๋ผ์ด์ธํธ์ ์๋ฒ๊ฐ ์ผ๋์ผ๋ก ์ฐ๊ฒฐํ๋ ๋ฐฉ์์ ๋๋ค.
๋๋ถ๋ถ ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ์ฐ๊ฒฐ๋์ด ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๊ณ ์๋ต๋ฐ๋ ๋จ์ํ ๊ฐ๋ ์ผ๋ก ์ดํดํ ์ ์์ต๋๋ค.
์) ์น ํ์ด์ง๋ฅผ ๋ณผ ๋ ์ฌ์ฉํ๋ HTTP ํ๋กํ ์ฝ, ํ์ผ ์ ์ก์ ์ํ TFP ํ๋กํ ์ฝ, ๋ฉ์ผ์ ์ฃผ๊ณ ๋ฐ๋ POP3 ํ๋กํ ์ฝ
- 3-tier ์ฐ๊ฒฐ ๋ฐฉ์
3-tier ์ฐ๊ฒฐ ๋ฐฉ์์ ์ฌ์ฉํ์ฌ ์์ฉ ์๋ฒ์ ๋ฐ์ดํฐ ์๋ฒ๋ก ๋๋์ด ์๋ฒ๋ฅผ ๊ตฌ์ฑํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ถ๋ฆฌํ ์ ์์ด ์ค๊ฐ์ ๋น์ฆ๋์ค ๋ก์ง(Business Logic)์ ์ฒ๋ฆฌํ๋ ์์ฉ ์๋ฒ๊ฐ ์ข ๋ ๋ค์ํ ์ญํ ์ ํ ์ ์๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
๋จ๋ง ๊ฐ์ ํต์ ์ด ์ผ๋ฐํ๋๋ฉฐ ํด๋ผ์ด์ธํธ์ ์๋ฒ์ ๊ด๊ณ๋ peer-to-peer ํต์ ์ผ๋ก ๋ถ๋ฆฌ๋ 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>
[์คํ ๊ฒฐ๊ณผ]
์ ๋ ฅ ์์์
์์ ์ฃผ์ ์ ๋ ฅ ํ ์์ฒญํ๊ธฐ ๋ฒํผ์ ๋๋ฅด๋ฉด


์๋ฌ๋ก ๊ฒฐ๊ณผ๊ฐ ๋์ค์ง ์๋๋ค. (ํด๊ฒฐ : ์ธํฐ๋ท ์ ๊ทผ ๊ถํ ์ค์ (manifestํ์ผ) + printlnํจ์ handler ๊ฐ์ฒด ์ด์ฉํด ์ฌ์ ์)

์ ๋ ฅํ ์ฃผ์๋ ์ํ ์ ๋ณด๋ฅผ ๋ฐ์์ฌ ์ ์๋๋ก ์คํ๋์ด์๋ ์ฃผ์ ์ค ํ๋์ ๋๋ค. ์ฃผ์ ์์ key๊ฐ์ ์ง์ ์ฌ์ดํธ์ ๋ฑ๋กํ์ฌ ๋ฐ๊ธ๋ฐ์ ์ ์์ต๋๋ค.
์๋ต ๊ฒฐ๊ณผ๋ฌผ์ ํฌ๋ฉง์ JSON ๋ฌธ์์ด์ ๋๋ค.
4. Volley ์ฌ์ฉํ๊ธฐ
์น์๋ฒ์ ์์ฒญํ๊ณ ์๋ต์ ๋ฐ์ ๋ HttpURLConnection ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ ์์ง๋ง,
์์ฒญ๊ณผ ์๋ต์ ํ์ํ ์ฝ๋์ ์์ด ๋ง๊ณ , ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๋ฉด์ ๋ฃ์ด์ผ ํ๋ ์ฝ๋์ ์๋ ๋ง์ต๋๋ค.
๋ํ ํธ๋ค๋ฌ์ ๋ํ ์ดํด๊ฐ ์๋ค๋ฉด ์ฑ์ด ๋น์ ์ ์ข ๋ฃ๋ ์๋ ์์ต๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ง๋ค์ด์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ Volley์ ๋๋ค.
Volley ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์น ์์ฒญ๊ณผ ์๋ต์ ๋จ์ํ ํ๊ธฐ ์ํด ๋ง๋ค์ด์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ๋๋ค.
Volley๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด
๋จผ์ (1) ์์ฒญ(Request) ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ (2) ์ด ์์ฒญ ๊ฐ์ฒด๋ฅผ ์์ฒญ ํ(RequestQueue)์ ๋ฃ์ด์ฃผ๋ฉด ๋ฉ๋๋ค.
๊ทธ๋ฌ๋ฉด ์์ฒญ ํ๊ฐ ์์์ ์น์๋ฒ์ ์์ฒญํ๊ณ ์๋ต๊น์ง ๋ฐ์์ค๋๋ค.
์ด ์๋ต์ ๋ฐ์ ์ ์๋๋ก ์ง์ ๋ ๋ฉ์ค๋๋ฅผ ๋ง๋ค์ด๋๊ธฐ๋ง ํ๋ฉด ์๋ต์ด ์์ ๋ ๋ฉ์๋๊ฐ ์๋ ํธ์ถ ๋ฉ๋๋ค.
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์ผ๋ก ์๋ต ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ (SampleRequest2)
'๐STUDY > ๐AndroidStudio' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๋๋ก์ด๋์คํ๋์ค] 11. ๋จ๋ง์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ด์ฉ ์ ๊ณต์ ๋ง๋ค๊ธฐ (0) | 2020.05.31 |
---|
๋๊ธ