본문 바로가기
Spring/SpringBoot

[SpringBoot] encodeURIComponent, decodeURIComponent 사용하기

by J4J 2022. 12. 29.
300x250
반응형

안녕하세요. 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에서는 인코딩하는 문자들을 찾아 다시 원복을 시켜주면 될 것 같습니다.

 

 

728x90

 

 

정확히 일치하지 않아도 되는 이유

 

일반적으로 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 사용하는 방법에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

 

 

 

728x90
반응형

댓글