본문 바로가기
프로그래밍

RestTemplate 사용시 URL 인코딩 이슈

by 탁구치는 개발자 2019. 10. 4.

RestTemplate 사용 시 파라미터 값이 자동으로 인코딩 되는 현상을 발견하게 되었다.

전송되는 URL은 다음과 같은데 파라미터 값에 특수문자들이 들어간다.

http://api.com?param=ABCDE+=,$%ABCDE


이와 같이 상대 서버로 요청을 보내면 파라미터 값에 ABCDE+=,$%ABCDE 가 들어 있어야 하는데 인코딩된 값으로 전달 된다고 한다.

실제 개발되어져 있는 코드를 보면 인코딩한 흔적이 없었다.

구글 검색을 해보니 url 을 넘겨주는 아규먼트가 String 타입이면 URL 인코딩이 자동으로 발생한다고 설명되어져 있다.

정말로 그런지 확인을 위해서 테스트 코드를 작성해 보았다.

테스트 코드에 나와 있는 것 처럼 url 을 넘겨주는 아규먼트에 uri.toString() 과 같이 String 타입으로 전달했다.

1
2
3
4
5
6
@Test
public void test() {
    UriComponents uri = UriComponentsBuilder.fromHttpUrl("http://api.com").queryParam("param""ABCDE+=,$%ABCDE").build();
    ResponseEntity<String> response = restTemplate.getForEntity(uri.toString(), String.class);
    assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
}
cs


정말로 다음과 같이 일부 특수문자가 인코딩 된다.

http://api.com?param=ABCDE+%3D,$%25ABCDE


해결 방법은 String 타입으로 URL을 넘겨주는 것이 아니라 URI 타입으로 넘겨주면 인코딩되지 않은 값으로 전달된다고 한다.

테스트 해보니 의도한 것과 같이 인코딩되지 않은 값으로 전송이 된다.

uri.toUri() 과 같이 URI 타입으로 전달했다.

1
2
3
4
5
6
@Test
public void test2() {
    UriComponents uri = UriComponentsBuilder.fromHttpUrl("http://api.com").queryParam("param""ABCDE+=,$%ABCDE").build();
    ResponseEntity<String> response = restTemplate.getForEntity(uri.toUri(), String.class);
    assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
}
cs


문제를 해결했지만 특수문자가 들어가는 파라미터 같은 경우들은 GET 방식으로의 연동이 아닌 POST 방식으로의 연동이 더 좋을 듯 싶다.

헌데 한편으로는 이런 생각도 든다.

RESTful 하게 개발된 서버로 데이터 검색을 할 때에는 POST를 쓰면 안되는데 이런 경우는 어떻게 해야 하나?

RestTemplate을 사용하면서 위와 같은 이슈가 발생할 수도 있다는 것을 인지한다면 GET 을 써도 큰 무리가 없지만 이런 것들은 꼭 운영을 하면서 갑작스럽게 발생하는 경우가 많다.