Android UrlQuerySanitizer getValue error

2024. 2. 6. 00:30·Dev experience/Android
728x90
반응형

이번에는 안드로이드 UrlQuerySanitizer를 Url Query를 파싱하는데 사용하지 않을 때 생긴 문제를 다루고자 한다.

 

문제 발생 배경

최근 새 프로젝트를 진행 중, API 응답이 json, xml, csv와 같은 형식이 아닌

URL의 GET method 사용 시 붙어있는 Query 형식으로 body 값을 주는 녀석이 있었다.

 

물론 반복문을 사용해서 일일히 파싱할 수도 있었지만,

Retrofit에서 json, xml 형식을 곧장 객체로 변환해주는 기능을 맛 본 이상 그 전으로 돌아가긴 싫었다.

 

그래서 찾다 보니 우회할 방법으로써 찾은 녀석이 UrlQuerySanitizer였다.

 

알고 보니 API level 1부터 유구한 역사를 가진 친구였지만 처음 들어봤다.(^^)

 

UrlQuerySanitizer.getValue 메소드를 사용해

어떤 파라미터의 값을 가져오려 했는데 그 값이 한글인 경우 제대로 파싱하지 못했다.

 

그럼 이제 뭐가 문제의 원인이었을까?

 

문제 원인

UrlQuerySanitizer 객체 생성 시, url를 파싱하는데 이 안에서 parseQuery 메소드를 호출한다.

UrlQuerySanitizer parseUrl method

 

문제는 parseQuery 메소드 안에서 StringTokenizer에서 if-else 문을 통해 parseEntry 메소드를 호출하는 부분이다.

UrlQuerySanitizer parseQuery method

 

그럼 다시, parseEntry에서 parameter와 value를 unescape 메소드로 통과시키는데

UrlQuerySanitizer parseEntry method

 

이 때, unescape 메소드는 ASCII 코드 내의 문자열을 처리할 수 있기 때문에

UTF-8 방식의 다른 문자열이 들어오면 이상한 값이 리턴된다.

UrlQuerySanitizer unescape method

 

해결

그럼 결국 unescape 메소드를 통과하면 안되는데 이를 어떻게 해결할까 고민했다.

 

답은 parseQuery 메소드를 그대로 가져오자!

val queryString = HashMap<String, String>()

val tokenizer = StringTokenizer(response.body(), "&")
while (tokenizer.hasMoreElements()) {
	val attributeValuePair = tokenizer.nextToken()
	if (attributeValuePair.isNotEmpty()) {
		val assignmentIndex = attributeValuePair.indexOf('=')
		if (assignmentIndex < 0) {
			queryString[attributeValuePair] = ""
		} else {
			queryString[attributeValuePair.substring(0, assignmentIndex)] =
				attributeValuePair.substring(assignmentIndex + 1)
		}
	}
}

 

여기서 response.body() 는 눈치가 빠른 사람이라면 Retrofit의 Response body 값이다.

 

짧은 예시를 들면 아래와 같은 바디 값을 queryString.getValue 메소드를 호출해서 파싱할 수 있다.

count=3&sentiment=보통&weather=맑음&account=normal

 

역시 라이브러리를 가져다 쓸 때는 원래 의도한 용도대로 쓰는 것이 정신 건강에 좋을 것 같다.

 

어쩌다 보니 자충수를 둔 것 같지만 나름 좋은 공부가 되었다.

728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'Dev experience > Android' 카테고리의 다른 글

Android Selector 사용 시 주의사항  (1) 2024.04.06
Android Change TextField Cursor Color  (0) 2024.03.13
Android ADB로 크래시 로그 저장하기  (0) 2024.02.03
Android ADB로 스크린샷 저장하기  (0) 2024.02.01
Android TextClock format 지정하기  (1) 2024.01.01
'Dev experience/Android' 카테고리의 다른 글
  • Android Selector 사용 시 주의사항
  • Android Change TextField Cursor Color
  • Android ADB로 크래시 로그 저장하기
  • Android ADB로 스크린샷 저장하기
BonusTrack02.dev
BonusTrack02.dev
공부, 일상
  • BonusTrack02.dev
    BonusTrack02.dev
    BonusTrack02.dev
  • 전체
    오늘
    어제
    • 분류 전체보기 (241)
      • Dev experience (88)
        • Android (87)
        • Kotlin (1)
      • Study (64)
        • Kotlin (28)
        • Swift (17)
        • Java (19)
      • 프로그래머스 (68)
      • 주저리주저리 (21)
        • 카페 (5)
        • 음식점 (4)
        • 컨퍼런스 (1)
        • 팝업스토어 (4)
        • 전시회 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    viewModelScope
    room
    coroutines
    배열
    스위프트
    Java
    jetpack
    안드로이드
    코틀린
    CodeLab
    PCCE
    오블완
    ViewModel
    aac
    ios
    LiveData
    android
    databinding
    Kotlin
    daterangepicker
    programmers
    코루틴
    SWIFT
    Observer
    자바
    프로그래머스
    Material
    티스토리챌린지
    MVVM
    getNumericValue
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
BonusTrack02.dev
Android UrlQuerySanitizer getValue error
상단으로

티스토리툴바