ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Http에서 국가 정보 얻기
    극락코딩 2023. 8. 17. 00:14
    한국이 아닌, 다른 나라에서 접근하는 유저에 대해 다국어 지원, 혹은 별도의 필터링을 해야 되는 작업이 있을 수 있다. 이럴때, 어떻게 국가 정보를 얻을 것인지 혼란스러울 수 있다.

     

     

    사실, 라우팅하는 쪽에서 심어주어도 될 것 같긴한데, 그것 말고 Http Header 기반으로 체크하는 방법도 있다.

    (이게 가장 간단하긴 함,, 하지만 정확성은 떨어진다.. 어쩔 수 없음)

     

    Http Header 중에서, accept-language 라는 항목이 있다. 해당 항목에 데이터 요청시 어떤 언어를 어떤 순위로 지정할 것인지 들어 있다. 자세한건.. 요기서

     

     

     

    아래의 코드를 참고하면, 아주 쉽게 Country Check 기능 구현 가능~!

     

     

    전체코드

    import mu.KotlinLogging
    import org.springframework.http.HttpHeaders
    import org.springframework.http.ResponseEntity
    import org.springframework.stereotype.Service
    import org.springframework.web.bind.annotation.GetMapping
    import org.springframework.web.bind.annotation.RequestHeader
    import org.springframework.web.bind.annotation.RequestMapping
    import org.springframework.web.bind.annotation.RestController
    
    @RestController
    @RequestMapping(value = ["/api/country-checker/v1"])
    class CountryCheckRestController(
        private val countryCheckService: CountryCheckService
    ) {
        private val logger = KotlinLogging.logger {}
    
        @GetMapping
        fun checkCountry(
            @RequestHeader headers: HttpHeaders
        ): ResponseEntity<CountryCheckResponse> {
            val country = countryCheckService.checkLanguage(headers)
            return ResponseEntity.ok(CountryCheckResponse.from(country))
        }
    }
    
    @Service
    class CountryCheckService {
        companion object {
            val languageHeadersKey = listOf("accept-language", "Accept-Language")
        }
    
        fun checkLanguage(headers: HttpHeaders): CountryCode {
            val key = languageHeadersKey.firstOrNull { key -> headers[key] != null }
                ?: return CountryCode.KOREA
    
            return headers[key]!!.mapNotNull { value -> CountryCode.of(value) }
                .ifEmpty { return CountryCode.KOREA }.first()
        }
    }
    
    enum class CountryCode(val korName: String) {
        KOREA("한국") {
            override fun check(value: String): Boolean {
                listOf("ko", "kr").firstOrNull {
                    value.contains(it)
                } ?: return false
    
                return true
            }
        },
        JAPAN("일본") {
            override fun check(value: String): Boolean {
                listOf("ja").firstOrNull {
                    value.contains(it)
                } ?: return false
    
                return true
            }
        };
    
        abstract fun check(value: String): Boolean
    
        companion object {
            fun of(value: String): CountryCode? {
                return values().firstOrNull { code -> code.check(value) }
            }
        }
    }
    
    data class CountryCheckResponse(
        val countryCode: CountryCode,
        val korName: String
    ) {
        companion object {
            fun from(countryCode: CountryCode): CountryCheckResponse {
                return CountryCheckResponse(
                    countryCode = countryCode,
                    korName = countryCode.korName
                )
            }
        }
    }

     

    참고

    - github

극락코딩