77일차(2)/Android App(38) : Http POST방식 요청하기(1)
- 새 모듈 생성
step17httprequest
acitivity_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">
<EditText
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:focusable="false"
android:id="@+id/editText"
android:background="#00ff00"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:id="@+id/inputUrl" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="요청"
android:id="@+id/requestBtn"/>
</LinearLayout>
</LinearLayout>
- 웹서버는 html 형식의 문자를 출력해준다.
- http 요청을 java 코드로 할 수 있을까? 어떻게 해야할까?
→ 웹브라우저에 java 코드로 직접 http요청을 할 수 있다.
→ 이 http요청을 통해 나중에 xml 이나 json 문자열을 받아올 것이다.
→ 이것을 안드로이드로 파싱해서 안드로이드 UI에 출력되도록 할 예정이다.
- 웹서버 연동을 위한 준비작업!
- 웹 서버에서 나오는 이런 브라우저의 코드를 java 코드를 사용해서 읽어오겠다!
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.MyAndroid"
android:usesCleartextTraffic="true">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
- 인터넷 사용 허가를 위해서는 이렇게 2개의 설정이 필요
MainActivity
package com.example.step17httprequest;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText=findViewById(R.id.editText);
EditText inputUrl=findViewById(R.id.inputUrl);
Button requestBtn=findViewById(R.id.requestBtn);
//요청 버튼을 클릭했을때 동작할 준비
requestBtn.setOnClickListener(v -> {
//입력한 요청 url을 읽어온다.
String url=inputUrl.getText().toString();
//http 요청은 시간이 오래 걸릴 수 있는 불확실한 작업이다. => 비동기 task에서 작업해야 한다.
new RequestTask().execute(url);
});
}
class RequestTask extends AsyncTask<String, Void, String>{
@Override
protected String doInBackground(String... strings) {
//문자열을 누적시킬 객체
StringBuilder builder=new StringBuilder();
//strings의 0번 방에 요청 url이 들어있다.
try {
//요청 url을 생성자의 인자로 전달해서 URL 객체를 생성한다.
URL url=new URL(strings[0]);
//UrlConnection 객체를 원래 type(자식 type) 으로 casting해서 받는다.
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
//정상적으로 연결이 되었다면
if(conn != null){
conn.setConnectTimeout(20000); //응답을 기다리는 최대 대기 시간
conn.setRequestMethod("GET"); //요청 메소드 설정 (Default는 GET)
conn.setUseCaches(false); //캐쉬 사용 여부
//응답 코드를 읽어온다.
int responseCode=conn.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK){ //정상 응답이라면
//문자열을 읽어들일 수 있는 객체의 참조값 얻어오기
BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream()));
//반복문 돌면서
while (true){
//문자열을 한줄씩 읽어들인다.
String line=br.readLine();
if(line==null)break;
//stringBuilder 객체에 읽어들인 문자열을 누적시킨다.
builder.append(line);
}
};
}
} catch (Exception e) {
Log.e("RequestTask 클래스", e.getMessage());
}
//StringBuilder객체에 누적된 문자열을 String 타입으로 한번에 얻어내서 리턴해준다.
return builder.toString();
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
//여기는 UI thread이고 s에는 서버가 응답한 문자열이 들어있다.
editText.setText(s);
}
}
}
- http요청은 새로운 스레드에서 작업 (시간이 오래 걸릴 수 있는 불확실한 작업이라서)
- 응답되는 문자열(return) url 은 onCreate() 에서 doInBackGround 로 전달한다.
- URL은 java.net 패키지
- exception이 발생하면 alt+enter로 try/catch 문으로 묶어주면 된다.
- urlConnection객체가 리턴되는 메소드 openConnerction() 으로 작업한다.
- get방식으로 요청한다.
- 저 코드 1줄은 생략할 수 있다.(GET방식 전송이 디폴트이다)
- getInputStream() 메소드로 httpUrlConnection 타입으로 넣어주기
- 반복문 돌아서 읽어내서 출력한다!
- 코드를 읽어온다. 200은 정상응답! 응답 실패하면 404번, 리다일렉트는 300번대, 서버 에러 500번 등..
- 해당 값들은 상수값으로도 정의되어 있으므로 상수로 사용!
- http가 정상 응답된다면 문자열을 읽어들인다.
- 매번 새 참조값을 새성하는것이 아니라 기존문자열에 연결하여 출력하게 만들기!
String line=br.readLine();
if(line==null)break;
builder.append(line);
- 반복문을 돌면서 문자를 연결하게 되면,
만약 웹서버가 응답하는 문자열이 1000줄 있다고 하면 필요없이 참조값이 1000개나 나온다.
- 이럴때에는 다른객체를 사용해야 한다. StringBuilder 객체 사용
- .append() 로 누적시키면 가비지 값이 덜 나온다.
- 누적된 문자열을 한번에 얻어낼 수 있다. 이 누적된 값을 리턴해주면 된다!
- builder 안에다가 한줄 한줄을 누적시켜서 리턴시키기.
- builder가 필요한데, 이 if문 안에서만 사용할 수 있으므로 참조가 안된다.
- 좀더 넓은 범위에서 쓸 수 있도록, doinBackGround() 메소드안에 선언
- 이곳의 리턴된 데이터는 onpostExcute() 에서 받아서 출력된다.
- url을 입력하면 daum.net에서 http 요청한 html문자열을 출력해준다.
- 안드로이드와 웹서버 연동의 기초이다.
- 지금 여기서는 html문자를 해석할 수는 없어서 이렇게 출력되지만,
만약 json문자열이라면? parsing 해서 원하는 방식으로 활용할 수 있다.
- java코드로 요청해서 서버에서 json문자열을 받아서, 원하는 정보를 뽑아내서 사용할 수 있다.
- 이전에 sts에서 만든 파일을 요청 api를 만들어 놓고 이렇게 요청하면 회원목록을 json문자열로 출력할 수 있다.
- 이 요청에 응답할 컨트롤러를 Spring에서 미리 만들어놓으면 응답시킬 수 있다.
ex) 이런 http 응답방식으로 할 수 있는 것이 많다.
만약 앱에서 회원가입을 한다고 하면,
→ java코드로 앱에서 입력받은 정보를 읽어와서
→ 웹서버에 post 방식으로 제출
→ DB에 저장
→ 사용자에게 json으로 응답할 수도 있다.
- 이런 작업을 하기 위해서는 비동기 task가 필요하다!
'국비교육(22-23)' 카테고리의 다른 글
77일차(4)/Android App(40) : Http POST방식 요청하기(3) (0) | 2023.01.30 |
---|---|
77일차(3)/Android App(39) : Http POST방식 요청하기(2) (0) | 2023.01.30 |
77일차(1)/Android App(37) : AsyncTask(2) (0) | 2023.01.27 |
76일차(4)/Android App(36) : AsyncTask(1) (0) | 2023.01.27 |
76일차(3)/Android App(35) : WebView (1) | 2023.01.26 |