ANDROID/Android 앱 프로그래밍

[Android] 웹으로 요청하기

주 녕 2021. 6. 30. 03:45
728x90

모든 내용은 Do it! 안드로이드 앱 프로그래밍을 바탕으로 정리한 것입니다. 

 

웹으로 요청하기

비연결성(stateless)인 HTTP 프로토콜은 페이지 정보를 요청할 때마다 소켓을 새로 연결하고 응답을 받은 다음에는 일반적으로 소켓 연결을 끊음. 그리고 그 소켓 연결 위에서 HTTP 프로토콜에 맞는 요청을 보내고 응답을 받아 처리함.

 

HTTP로 웹 서버에 접속하기

자바에서 HTTP 클라이언트를 만드는 가장 간단한 방법(소켓과 마찬가지로 표준 자바 방식 그대로 사용 가능)은

URL 객체를 만들고 이 객체의 openConnection() 메서드를 호출하여 HttpURLConnection 객체를 만드는 것!

public URLConnection openConnection()
  • URL 객체에 들어있는 문자열이 "http://"를 포함하면 HTTP 연결을 위한 객체를 만들게 됨
  • openConnection() 메서드가 리턴하는 URLConnection 객체를 HttpURLConnection으로 형변환하여 사용 가능
  • HttpURLConnection 객체로 연결할 경우, GET 또는 POST와 같은 요청 방식과 함께 요청을 위한 파라미터 설정 가능
public void setRequestMethod(String method)
public void setRequestProperty(String field, String newValue)
  • setRequestMethoid() : 요청 방식을 지정하는 메서드로, GET이나 POST 문자열을 파라미터로 전달
  • setRequestProperty() : 헤더에 들어가는 필드 값을 지정

 

[ 예제 ]

HttpActivity.java

public class HttpActivity extends AppCompatActivity {

    EditText editText;
    TextView textView;

    Handler handler = new Handler();

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

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

        Button button = findViewById(R.id.http_btn);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                final String urlStr = editText.getText().toString();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        request(urlStr);
                    }
                }).start();
            }
        });
    }
  • 버튼을 누르면 사용자가 입력한 사이트 주소를 이용해 request() 메서드를 호출
  • request() 메서드 안에서 인터넷을 이용할 것이므로 스레드 안에서 동작하도록 스레드 객체를 생성하고 그 안에서 호출해야 함
    • 이전 포스팅에서 설명했지만, 안드로이드 현재 플랫폼 버전에서 네트워킹의 스레드 사용이 강제됨
  • 스레드에서 처리한 결과물을 화면에 띄우기 위해(UI 업데이트) 핸들러 객체를 만들어 둠
...
    public void request(String urlStr) {
        StringBuilder output = new StringBuilder();
        try {
            URL url = new URL(urlStr);

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            if (connection != null) {
                connection.setConnectTimeout(10000);
                connection.setRequestMethod("GET");
                connection.setDoInput(true);

                int resCode = connection.getResponseCode();
                if (resCode == HttpURLConnection.HTTP_OK) {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String line = null;
                    while (true) {
                        line = reader.readLine();
                        if (line == null) {
                            break;
                        }

                        output.append(line + "\n");
                    }
                    reader.close();
                    connection.disconnect();
                } else {
                    println("현재 요청 상태 : "+resCode);
                }
            }
        } catch (IOException e) {
            println("예외 발생함: "+e.toString());
        }

        println("응답 -> "+output.toString());
    }

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

 

*책의 예제 코드에서는 변수 resCode를 만들고 사용하지 않아 사용하는 코드로 변경함

  • request() 메서드 : 응답 결과물을 모아 화면에 출력
    1. 먼저 URL 객체 생성
    2. 파라미터로 전달된 URL 문자열을 이용한 객체의 openConnection() 메서드를 호출하여 HttpURLConnection 객체 생성
    3. 이 객체에 요청 방식(GET)을 설정하고 getResponseCode() 메서드를 호출 (내부적으로 웹서버에 페이지를 요청)
      • setConnectionTimeout() : 연결 대기 시간 설정 - 예제에서는 10초 동안 연결되기를 기다린다는 의미
      • setDoInput() : 이 객체의 입력이 가능하도록 만들어줌
    4. 응답코드가 HTTP_OK인 경우 정상적인 응답 / 요청 페이지가 없는 경우 HTTP_NOT_FOUND 코드 출력
      • readLine() : BufferedReader 클래스에 정의되어 있으므로 HttpUrlConnection 객체의 스트림을 이 클래스의 객체로 만든 후에 처리해야 함
  • println() 메서드 : 핸들러를 사용하여 화면에 있는 TextView의 append() 메서드 호출

 

AndroidManifest.xml

<manifest ...">

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

    <application
        ...
        android:usesCleartextTraffic="true">
  • android:usesCleartextTraffic  - 앱이 일반 텍스트 HTTP와 같은 일반 텍스트 네트워크 트래픽을 사용하는지 여부
    • API 레벨 27 이하를 타겟팅하는 앱에서는 기본값이 "true"이고, API 레벨 28 이상을 타겟팅하는 앱에서는 기본값이 "false"임
    • 이 속성이 "false" 설정되면 플랫폼 구성요소(ex. HTTP 및 FTP 스택, DownloadManager, MediaPlayer)는 앱의 일반 텍스트 트래픽 사용 요청을 거부함

 

 

 

 

*핸들러에 대한 자세한 내용은 아래 포스팅 참고!

 

[Android] 핸들러(Handler)

모든 내용은 Do it! 안드로이드 앱 프로그래밍을 바탕으로 정리한 것입니다. 핸들러(Handler) 새로운 프로젝트를 만들면 자동으로 생성되는 메인 액티비티는 앱이 실행될 때 하나의 프로세스에서

junyoung-developer.tistory.com

*사용한 OpenAPI URL : 영화진흥위원회 API

https://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=f5eef3421c602c6cb7ea224104795888&targetDt=20210101

728x90