[Android/Flutter 교육] 66일차

MSU·2024년 4월 5일

Android-Flutter

목록 보기
70/85
post-thumbnail

웹 통신 기초

GET

사용자가 서버로 전달하는 파라미터 데이터가 주소에 붙어져서 전달된다.
서버로 전달되는 데이터의 총량이 적다.
요청속도가 빠르다
서버로 전달하는 파라미터가 공개된다.
주소를 포함한 파라미터 데이터의 총 길이가 255글자를 넘지 못한다.
영문, 숫자, 특수문자 외의 다른 글자를 허용하지 않는다(띄어쓰기도 허용하지 않는다)
최근의 웹브라우저나 라이브러리들은 데이터에 띄어쓰기가 있으면 띄어쓰기에 해당하는 글자로 자동 변환해 서버로 전달해준다

POST

사용자가 서버로 전달하는 파라미터 데이터가 HTTP 요청 헤더에 담겨져서 전달된다.
서버로 전달되는 데이터의 총량이 많다.
요청 속도가 느리다(인간은 그 속도를 체감할 수 없음)
파라미터 데이터의 총량은 제한이 없다
모든 글자들을 허용한다

HTTP 요청 헤더

서버에 요청을 할 때 데이터를 숨겨서 전달할 수 있는 수단
HTTP 요청 헤더에 담아서 전달되는 데이터는 사용자가 알 수 없다.
서버에 요청을 하게 되면 기본적으로 몇 가지 데이터(단말기, 브라우저 정보 등)가 담기고
그 밖에 개발자가 추가적으로 데이터를 담아 전달할 수 있다.
API를 요청할때 헤더에 API키와 같은 데이터를 담아야 할게 있는지 반드시 개발 문서를 확인한다

오픈API 사용법

네이버 개발자 센터의 오픈api를 사용할 예정

사용 절차

  1. 반드시 관련 문서를 찾는다
  2. API 키(혹은 접속시 필요한 개발자 구분값) 발급 방법을 확인해야 한다.
  3. 요청할 페이지의 주소를 확인해야 한다.
  4. HTTP 요청 헤더로 전달할 데이터가 있는지 확인한다.
  5. 파라미터로 전달할 데이터가 있는지 확인한다.
  6. 요청방식(GET or POST)을 확인한다.
  7. 서버가 전달해주는 데이터의 양식을 확인한다.
  8. 오류 코드를 확인한다.
  9. POSTMAN을 이용해 요청 테스트를 한다.

검색 API

Products > 서비스 API > 검색 클릭

애플리케이션 등록

요청 URL 확인

요청 방식을 확인

HTTP 요청 헤더로 전달할 데이터가 있는지 확인

발급받은 클라이언트 ID, 클라이언트 시크릿

파라미터로 전달할 데이터가 있는지 확인

포스트맨으로 테스트

크롬브라우저 확장프로그램을 이용

URL을 입력한다

헤더를 추가하여 필요한 내용을 넣는다.

필요한 파라미터를 추가한다

모든 입력이 완료되면 Send 버튼을 누른다

결과가 잘 나오는지 확인한다

이제 Retrofit을 이용해 네이버api를 호출한다

Retrofit

안드로이드에서 http통신을 도와주는 라이브러리
OkHttp를 만든 그룹이 만든 라이브러리다

라이브러리의 사용법 보다는 네트워크 통신 구조를 이해하고 있어야 한다

AndroidManifest.xml에 권한 추가

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

build.gradle에 관련 라이브러리 추가

    implementation("com.squareup.retrofit2:retrofit:2.11.0")
    implementation("com.squareup.retrofit2:converter-gson:2.11.0")
    implementation("com.squareup.retrofit2:converter-scalars:2.11.0")
    implementation("com.google.code.gson:gson:2.10.1")

서버에서 전달받은 결과값을 담을 클래스 추가

서버가 전달해주는 데이터를 확인하고 데이터 클래스를 만들면 된다.
각 프로퍼티도 동일한 이름으로 맞춰줘야 나중에 서버에서 받아온 데이터를 Retrofit이 자동으로 프로퍼티에 담아준다.
만약 프로퍼티가 다른 이름이라면 어노테이션을 이용해 각 프로퍼티에 맞는 데이터를 담을 수 있게 해줘야 한다.

// ResultNews.kt


data class ResultNews (
    var lastBuildDate:String = "",
    var total:Int = 0,
    var start:Int = 0,
    var display:Int = 0,
    var items:List<ItemClass>
)

data class ItemClass(
    var title:String = "",
    var originallink:String = "",
    var link:String = "",
    var description:String = "",
    var pubDate:String = ""
)

GET 요청은 @GET을 사용한다.

@GET("news.json")

헤더 정보와 파라미터 정보를 설정하는 메서드

    fun getSearchNews(
        // 헤더 정보
        @Header("X-Naver-Client-Id") clientId : String,
        @Header("X-Naver-Client-Secret") clientSecret : String,
        // 파라미터
        @Query("query") query:String,
        @Query("disply") display:Int,
    ): Call<ResultNews>

반환타입 Call은 서버에서 전달받은 데이터를 ResultNews클래스로 만든 객체에 담아 반환해준다

전체 코드

interface NaverAPI {
    @GET("news.json")
    fun getSearchNews(
        // 헤더 정보
        @Header("X-Naver-Client-Id") clientId : String,
        @Header("X-Naver-Client-Secret") clientSecret : String,
        // 파라미터
        @Query("query") query:String,
        @Query("disply") display:Int,
    ): Call<ResultNews>
}

API 호출

// MainActivity.kt

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(activityMainBinding.root)

        activityMainBinding.apply {
            buttonRequest.setOnClickListener {
                textViewResult.text = ""

                // 요청을 위한 Retrofit 객체를 생성한다.
                val retrofitBuilder = Retrofit.Builder()
                // 기본 주소
                retrofitBuilder.baseUrl("https://openapi.naver.com/v1/search/")
                // 가져온 데이터를 분석하여 객체에 담아줄 도구를 설정한다.
                // JSON 양식의 문서이므로 GsonConverter를 사용한다.
                retrofitBuilder.addConverterFactory(GsonConverterFactory.create())

                val retrofit = retrofitBuilder.build()

                // 요청을 위해 사용할 객체
                // 앞서 만든 NaverAPI 인터페이스(요청에 필요한 정보를 가진 인터페이스)를 지정한다.
                val api = retrofit.create(NaverAPI::class.java)
                // 요청 객체를 추출한다.
                // 이 때, 요청을 위한 인터페이스의 메서드를 호출한다.
                val clientId = "3wT8IvSRXkg7PfOlvYHy"
                val clientSecret = "qS9iNfixmx"
                val keyword = inputKeyword.text.toString()
                val display = 100
                val callNews = api.getSearchNews(clientId, clientSecret, keyword, display)

                // 요청한다.
                // 요청이 완료되면 동작할 콜백을 설정해준다
                callNews.enqueue(object : Callback<ResultNews>{
                    // 요청에 성공 했을 때
                    override fun onResponse(call: Call<ResultNews>, response: Response<ResultNews>) {
                        // 서버로 부터 가져온 JSON 데이터는 이미 분석이 완료되어 객체에 담겨져서 전달된다.
                        // 객체에 담겨져 있는 데이터를 필요한 용도로 사용한다.
                        response.body()?.apply {
                            textViewResult.append("lastBuildDate : ${lastBuildDate}\n")
                            textViewResult.append("total : ${total}\n")
                            textViewResult.append("start : ${start}\n")
                            textViewResult.append("display : ${display}\n")
                            
                            items.forEach {
                                textViewResult.append("title : ${it.title}\n")
                                textViewResult.append("originallink : ${it.originallink}\n")
                                textViewResult.append("link : ${it.link}\n")
                                textViewResult.append("description : ${it.description}\n")
                                textViewResult.append("pubDate : ${it.pubDate}\n")
                            }
                        }
                    }
                    // 요청에 실패 했을 때
                    override fun onFailure(call: Call<ResultNews>, error: Throwable) {
                        Log.e("test1234", "실패", error)
                    }
                })
            }
        }
    }
    

profile
안드로이드공부

0개의 댓글