URL 인코딩(Url Encoding)은 개발자가 기본적으로 알고 있어야 하는 개념이지만, 제대로 이해하지 않고 사용하면 예상치 못한 오류를 초래할 수 있습니다. 저 역시 이를 간과했다가 실수를 경험했고, 이번 기회에 제대로 정리해보고자 합니다.

URL Enocde 왜 필요해?
- URL에서는 일부 문자만 정상적으로 처리할 수 있다
- 허용되지 않은 문자가 포함되면 문제가 생길 수 있기에 URL Encode가 필요
- 일부 문자는 URL에서 특수한 의미를 가진다
그래서 누가 정했는데?
RFC 3986?
RFC 3986은 URI(Uniform Resource Identifier)의 문법과 문법 규칙을 정의하는 공식 문서로
즉, 웹에서 사용되는 URL(Uniform Resource Locator)과 URN(Uniform Resource Name)의 형식을 표준화하는 규칙을 담고 있다고 합니다.
URI 형식
- URI는 기본적으로 다음과 같은 일반적인 형식
- scheme://authority/path?query#fragment
| scheme | 프로토콜 (http, https, ftp, mailto) 등 |
| authority | 서버 주소 (dev-code.tistory.com) |
| path | 리소스 경로 (/category/dev) |
| query | 요청 파라미터 (?q=hello, ?id=3&name=JAN~DEC) |
| fragment | 페이지 내 특정 위치 (#section1, #top) |
예약된 문자 (Reserved Characters)
- URL에서 일부 문자는 특수한 의미를 가진다
- ! * ' ( ) ; : @ & = + $ , / ? # [ ]
| ? | 쿼리 문자열의 시작 |
| & | 여러 개의 파라미터 구분 |
| = | 키와 값 구분 |
| # | fragment |
| / | 디렉토리 경로 구분 |
비예약 문자 (Unreserved Characters)
- 알파벳: A-Z, a-z
- 숫자: 0-9
- 특수 문자: - _ . ~
- 이 외의 문자는 인코딩이 필요
- 비 예약 문자(unreserved)
URL Encode은 어떤 식으로 동작할까?
Java.net.URLEncoder의 URLEncoder.encode()는 특수 문자와 비 ASCII 문자를 퍼센트 인코딩(Percent Encoding, % 인코딩) 방식으로 변환합니다.
- Percent Encoding은 % + 16 진수로 우선 생각해 둡시다 자세하게 알고 싶으면 "Percent Encoding"으로 검색해 주세요.
String text = "+";
System.out.println(URLEncoder.encode(text, StandardCharsets.UTF_8)); // %2B
// "+" 를 16진수로 변환하면 "2B"로 변환되는걸 볼 수 있다
System.out.println(convertStringToHex(text)); // 2B
위 코드에서 + 문자를 URLEncoder.encode()로 인코딩하면 %2B 가 출력되는 걸 볼 수 있습니다.
"+"가 URL에서 공백( )을 나타내는 경우가 있어 혼동을 방지하기 위해 안전하게 %2B로 변환되기 때문입니다.
실무에서도 URI의 query부분에도 url encode를 적용하기도 하는데요.
실제로 Google에 "url encode"검색을 할 경우 아래와 같이 나오는 걸 볼 수 있습니다.
파라미터 q의 value로 url+encode 가 찍히는 걸 볼 수 있는데 공백을 "+"로 변환된 걸 볼 수 있습니다.

실무에서 Server-to-Server GET 요청을 처리할 때, UriComponentsBuilder와 RestTemplate을 조합하여 요청을 보냈습니다.
하지만, 빌더에서 생성한 URL이 RestTemplate로 전달되는 과정에서 인코딩이 의도한 대로 동작하지 않는 문제가 발생했습니다.
문제를 해결하긴 했지만, URL Encode 방식이나 예약어에 대한 기본 개념을 더 잘 이해하고 있었다면 원인을 더 빠르게 파악하고 해결할 수 있었을 것입니다.
이 경험을 통해, URL Encoding의 동작 방식과 표준을 제대로 이해하고 사용하는 것이 중요하다는 점을 다시금 깨달았고, 이를 정리하여 공유하면 비슷한 문제를 겪는 사람들에게 도움이 될 것이라 생각했습니다.
'개발' 카테고리의 다른 글
| Fixed length format과 getByte()의 예상치 못한 함정 (1) | 2025.03.11 |
|---|---|
| AWS 아키텍처 개선 하기 (0) | 2025.02.01 |
| Github Actions으로 서버배포 자동화하기 (1) (1) | 2024.11.17 |