안녕하세요. J4J입니다.
이번 포스팅은 encodeURIComponent, decodeURIComponent 사용하는 방법에 대해 적어보는 시간을 가져보려고 합니다.
정확히 일치해서 사용하기
먼저 encodeURIComponent와 decodeURIComponent는 자바스크립트에서 문자를 인코딩, 디코딩하기 위해 사용되는 함수로 URI를 구성할 때 일부 문자에 의해 발생되는 문제들을 해결할 때 주로 사용합니다.
그리고 이런 목적으로 사용되는 두 함수와 동일한 결과가 나오는 것을 스프링에서도 사용하고자 하는 상황들이 가끔씩 발생할 수 있습니다.
이런 목적을 달성하기 위해 자바에서는 URLEncoder와 URLDecoder를 제공합니다.
하지만 문제점은 URLEncoder의 결괏값은 encodeURIComponent의 결괏값과 항상 일치하지 않습니다.
간단한 예시로 다음과 같은 모든 문자들에 대한 테스트 결과물들이 있습니다.
// 자바스크립트
console.log(encodeURIComponent('`~!@#$%^&*()-_=+[{]}\\|;:\'",<.>/?'))
→ %60~!%40%23%24%25%5E%26*()-_%3D%2B%5B%7B%5D%7D%5C%7C%3B%3A'%22%2C%3C.%3E%2F%3F
console.log(decodeURIComponent(`%60~!%40%23%24%25%5E%26*()-_%3D%2B%5B%7B%5D%7D%5C%7C%3B%3A'%22%2C%3C.%3E%2F%3F`))
→ `~!@#$%^&*()-_=+[{]}\|;:'",<.>/?
// 자바
System.out.println(URLEncoder.encode("`~!@#$%^&*()-_=+[{]}\\|;:\'\",<.>/?", StandardCharsets.UTF_8));
→ %60%7E%21%40%23%24%25%5E%26*%28%29-_%3D%2B%5B%7B%5D%7D%5C%7C%3B%3A%27%22%2C%3C.%3E%2F%3F
System.out.println(URLDecoder.decode("%60~!%40%23%24%25%5E%26*()-_%3D%2B%5B%7B%5D%7D%5C%7C%3B%3A'%22%2C%3C.%3E%2F%3F", StandardCharsets.UTF_8));
→ `~!@#$%^&*()-_=+[{]}\|;:'",<.>/?
결과물을 확인해보면 일부 문자들에 대해 자바쪽에서 더 많은 인코딩을 하는 것을 확인할 수 있었습니다.
그리고 결과물이 서로 다르기 때문에 항상 동일한 결과가 나오는 것을 만들고자 여러 레퍼런스들을 찾아봤지만 관련 자료들을 찾을 수 없었습니다.
그래서 동일한 결과물을 만들어 내고자 다음과 같이 문자 하나하나 치환하는 메서드를 만들어봤습니다.
public String encodeUriComponent(String text) {
return text.replaceAll("\\%", "\\%25")
.replaceAll(";", "\\%3B")
.replaceAll(",", "\\%2C")
.replaceAll("/", "\\%2F")
.replaceAll("\\?", "\\%3F")
.replaceAll(":", "\\%3A")
.replaceAll("@", "\\%40")
.replaceAll("&", "\\%26")
.replaceAll("=", "\\%3D")
.replaceAll("\\+", "\\%2B")
.replaceAll("\\$", "\\%24")
.replaceAll("#", "\\%23")
.replaceAll("`", "\\%60")
.replaceAll("\\^", "\\%5E")
.replaceAll("\\[", "\\%5B")
.replaceAll("\\]", "\\%5D")
.replaceAll("\\{", "\\%7B")
.replaceAll("\\}", "\\%7D")
.replaceAll("\"", "\\%22")
.replaceAll("<", "\\%3C")
.replaceAll(">", "\\%3E")
.replaceAll("\\\\", "\\%5C")
.replaceAll("\\|", "\\%7C");
}
그리고 테스트를 해본 결과 다음과 같은 결과를 확인할 수 있었습니다.
// 자바스크립트
console.log(encodeURIComponent('`~!@#$%^&*()-_=+[{]}\\|;:\'",<.>/?'))
→ %60~!%40%23%24%25%5E%26*()-_%3D%2B%5B%7B%5D%7D%5C%7C%3B%3A'%22%2C%3C.%3E%2F%3F
// 자바
System.out.println(new Function().encodeUriComponent("`~!@#$%^&*()-_=+[{]}\\|;:\'\",<.>/?"));
→ %60~!%40%23%24%25%5E%26*()-_%3D%2B%5B%7B%5D%7D%5C%7C%3B%3A'%22%2C%3C.%3E%2F%3F
자바스크립트에서 encodeURIComponent와 동일한 결과물이 나오는 것을 확인할 수 있었습니다.
정확한 결과물을 얻고자 하시면 위의 코드를 사용하거나 또는 encodeURIComponent에서는 인코딩을 하지는 않지만 URLEncoder에서는 인코딩하는 문자들을 찾아 다시 원복을 시켜주면 될 것 같습니다.
정확히 일치하지 않아도 되는 이유
일반적으로 encodeURIComponet, decodeURIComponent를 사용하는 것은 위에서 제가 말한대로 URI를 구성할 때 문자에 의해 발생되는 문제들을 해결하기 위해서입니다.
그리고 추가 테스트를 해봤을때 다음과 같은 결과물을 확인할 수 있었습니다.
// 자바
System.out.println(URLEncoder.encode("`~!@#$%^&*()-_=+[{]}\\|;:\'\",<.>/?", StandardCharsets.UTF_8));
→ %60%7E%21%40%23%24%25%5E%26*%28%29-_%3D%2B%5B%7B%5D%7D%5C%7C%3B%3A%27%22%2C%3C.%3E%2F%3F
// 자바스크립트
console.log(decodeURIComponent(`%60%7E%21%40%23%24%25%5E%26*%28%29-_%3D%2B%5B%7B%5D%7D%5C%7C%3B%3A%27%22%2C%3C.%3E%2F%3F`))
→ `~!@#$%^&*()-_=+[{]}\|;:'",<.>/?
URLEncoder를 사용하여 인코딩한 문자열을 자바스크립트의 decodeURIComponent의 파라미터로 사용했을 때 인코딩하기 전 문자열을 그대로 확인할 수 있었습니다.
즉 스프링에서 URLEncoder를 이용하여 만든 URI를 자바스크립트에서 그대로 사용해도 문제없이 동작될 수 있다는 것입니다.
그러므로 이런 경우가 필요할 진 모르겠지만 인코딩된 값이 꼭 동일해야 되는 분들이 아니시라면 인코딩 결괏값이 다르더라도 URLEncoder를 그대로 사용해도 무방합니다.
이상으로 encodeURIComponent, decodeURIComponent 사용하는 방법에 대해 간단하게 알아보는 시간이었습니다.
읽어주셔서 감사합니다.
'Spring > SpringBoot' 카테고리의 다른 글
[SpringBoot] 엑셀 파일 생성하여 다운로드하기 (0) | 2023.01.18 |
---|---|
[SpringBoot] 이메일 발신하기 (0) | 2023.01.16 |
[SpringBoot] AWS Lambda로 배치 만들기 (3) - GitLab으로 자동배포하기 (0) | 2022.12.15 |
[SpringBoot] AWS Lambda로 배치 만들기 (2) - Lambda 생성해서 배포하기 (0) | 2022.12.12 |
[SpringBoot] AWS Lambda로 배치 만들기 (1) - Spring 세팅 및 로컬 테스트 (0) | 2022.12.05 |
댓글