본문 바로가기
에러 핸들링

UriComponentsBuilder 한글 적용이 잘 안될 때

by kdohyeon (김대니) 2023. 2. 9.
반응형

HTTP 요청을 위해 UriComponentsBuilder 를 활용했다. 코드는 다음과 같다.

var a = UriComponentsBuilder.fromUriString("http://external-service.com")
                .path("/api/v1/sample")
                .queryParam("query", "A B")
                .toUriString();

이렇게 해서 요청을 날려보니 다음과 같이 요청이 날아갔다.

GET http://external-service.com/api/v1/sample?query=A%20B

원하던게 이게 아닌데..

"A B" 처럼 스페이스가 포함되어야 하는데 인코딩이 잘못되는건지 "A%20B" 으로 요청이 날아가서 제대로된 응답을 받지 못했다.

UriComponentsBuilder 작동 방식

URL 에는 모든 문자를 담지 못하기 때문에 인코딩이 필요한데, UriComponentsBuilder 도 자체적으로 인코딩을 한다. UriComponentsBuilder 중 .build() 라는 체이닝 메소드가 존재한다.

.build() 를 실행하면 encoded 에 false 가 입력되면서 인코딩이 작동되지 않는다.

public UriComponents build() {
   return build(false);
}

/**
 * Variant of {@link #build()} to create a {@link UriComponents} instance
 * when components are already fully encoded. This is useful for example if
 * the builder was created via {@link UriComponentsBuilder#fromUri(URI)}.
 * @param encoded whether the components in this builder are already encoded
 * @return the URI components
 * @throws IllegalArgumentException if any of the components contain illegal
 * characters that should have been encoded.
 */
public UriComponents build(boolean encoded) {
    return buildInternal(encoded ? EncodingHint.FULLY_ENCODED :
            (this.encodeTemplate ? EncodingHint.ENCODE_TEMPLATE : EncodingHint.NONE));
}

해결

원하는 대로 하려면 .build() 를 해줘야 한다.

var a = UriComponentsBuilder.fromUriString("http://external-service.com")
                .path("/api/v1/sample")
                .queryParam("query", "A B")
                .build() // <-- 추가!
                .toUriString();

 

반응형

댓글