본문 바로가기

major/Android

[Kotlin] 네이버 오픈 API 검색 사용하기

이전 포스팅 ☛ [Android] 네이버 오픈 API 사용방법 - 예제 코드 사용

이전 포스팅 중에 JAVA로 네이버 오픈 API를 사용하는 방법을 정리한 적이 있습니다.

그때도 네이버에서 제공한 예제를 사용했었는데, 네이버에서는 JAVA로만 예제를 제공하기 때문에, Kotlin으로 예제 코드를 변경해봤습니다. 네이버에 API에서 ClientId, ClientSecret 값을 받는 방법은 이전 포스팅을 참고해주세요.

 

ApiExamSearchBlog.kt 파일을 생성합니다.

class ApiExamSearchBlog {

    val clientId = "클라이언트아이디값"
    val clientSecret = "클라이언트시크릿값"

    fun main() {

        var text: String? = null
        try {
            text = URLEncoder.encode("그린팩토리", "UTF-8")
        } catch (e: UnsupportedEncodingException) {
            throw RuntimeException("검색어 인코딩 실패", e)
        }

        val apiURL = "https://openapi.naver.com/v1/search/blog?query=" + text!!    // json 결과
        //String apiURL = "https://openapi.naver.com/v1/search/blog.xml?query="+ text; // xml 결과

        val requestHeaders : HashMap<String, String> = HashMap()
        requestHeaders.put("X-Naver-Client-Id", clientId)
        requestHeaders.put("X-Naver-Client-Secret", clientSecret)
        val responseBody = get(apiURL, requestHeaders)

        parseData(responseBody)

    }

    private operator fun get(apiUrl: String, requestHeaders: Map<String, String>): String {
        val con = connect(apiUrl)
        try {
            con.setRequestMethod("GET")
            for ((key, value) in requestHeaders) {
                con.setRequestProperty(key, value)
            }

            val responseCode = con.getResponseCode()
            return if (responseCode == HttpURLConnection.HTTP_OK) { // 정상 호출
                readBody(con.getInputStream())
            } else { // 에러 발생
                readBody(con.getErrorStream())
            }

        } catch (e: IOException) {
            throw RuntimeException("API 요청과 응답 실패", e)
        } finally {
            con.disconnect()
        }
    }

    private fun connect(apiUrl: String): HttpURLConnection {
        try {
            val url = URL(apiUrl)
            return url.openConnection() as HttpURLConnection
        } catch (e: MalformedURLException) {
            throw RuntimeException("API URL이 잘못되었습니다. : $apiUrl", e)
        } catch (e: IOException) {
            throw RuntimeException("연결이 실패했습니다. : $apiUrl", e)
        }

    }

    private fun readBody(body: InputStream): String {
        val streamReader = InputStreamReader(body)

        try {
            BufferedReader(streamReader).use({ lineReader ->
                val responseBody = StringBuilder()

                var line: String? = lineReader.readLine()
                while ( line != null) {
                    responseBody.append(line)
                    line = lineReader.readLine()
                }
                return responseBody.toString()
            })
        } catch (e: IOException) {
            throw RuntimeException("API 응답을 읽는데 실패했습니다.", e)
        }
    }

    private fun parseData(responseBody: String) {
        var title: String
        var jsonObject: JSONObject? = null
        try {
            jsonObject = JSONObject(responseBody)
            val jsonArray = jsonObject.getJSONArray("items")

            for (i in 0 until jsonArray.length()) {
                val item = jsonArray.getJSONObject(i)
                title = item.getString("title")
                println("TITLE : $title")
            }

        } catch (e: JSONException) {
            e.printStackTrace()
        }

    }
}

MainActivity.kt에서 다음과 같이 불러옵니다.

Thread로 실행해야 NetworkOnMainThreadException 에러가 나지 않습니다.

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val thread = Thread({
            var apiExamSearchBlog = ApiExamSearchBlog()
            apiExamSearchBlog.main()
        }).start()
    }
}

실행 화면은 다음과 같습니다.

실행

그린 팩토리를 검색해서 검색 결과 문서의 TITLE만 출력하도록 했습니다.

요청 변수, 출력 결과와 같은 정보는 네이버 개발자 홈페이지에서 가이드를 참고하면 됩니다.

위 HttpURLConnection 예제를 조금만 응용하면 다양한 API를 가져올 수 있습니다.

저는 공공 데이터도 사용해봤는데, 그부분도 정리해서 포스팅해보겠습니다.


잘못된 내용이 있다면 언제든지 댓글이나 메일로 알려주시면 감사하겠습니다.

이 포스팅이 도움이 되었다면 공감 부탁드립니다.

궁금한 점은 언제든지 댓글 남겨주시면 답변해드리겠습니다:D