๋ฐ˜์‘ํ˜•

๐Ÿš€ URL ์ธ์ฝ”๋”ฉ ์•Œ๊ธฐ


URL ์ธ์ฝ”๋”ฉ์€ ์›น ๋ธŒ๋ผ์šฐ์ €์™€ ์›น ์„œ๋ฒ„๊ฐ€ URL์„ ์•ˆ์ „ํ•˜๊ฒŒ ์†ก์‹ ํ•˜๊ธฐ ์œ„ํ•œ ์ธ์ฝ”๋”ฉ ๋ฐฉ์‹์ด๋‹ค.

๋ณดํ†ต ์œ ๋‹ˆ์ฝ”๋“œ์˜ Charset์ธ UTF-8 ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ๋‹ค.

๊ณต๋ฐฑ ๋ฌธ์ž +, %20

URL ์ธ์ฝ”๋”ฉ์„ ๋ณด๋ฉด ๊ณต๋ฐฑ์„ + ๋˜๋Š” %20์œผ๋กœ ํ‘œํ˜„๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. +๋Š” ๋ ˆ๊ฑฐ์‹œ๋กœ ๋งŽ์ด ์“ฐ์˜€๊ณ ,

%20์ด ํ‘œ์ค€์ด๊ธฐ ๋•Œ๋ฌธ์— %20์ด ์ฃผ๋กœ ์“ฐ์ธ๋‹ค. ๋ฌด์—‡์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”๊ฐ€๋Š” ์ •๋‹ต์€ ์—†๊ณ ,

์ •ํ•˜๊ธฐ ๋‚˜๋ฆ„์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ทœ์น™์„ ์ •ํ•˜๊ณ  ๋”ฐ๋ฅด๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

๐Ÿš€ Problem


URL ์ธ์ฝ”๋”ฉ ๊ณต๋ฐฑ์˜ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค.

URL๋กœ ๋„˜์–ด์˜ค๋Š” ๊ฒƒ(location)์€ โ€œ์•ˆ๋…•ํ•˜์„ธ์š”%20์ €๋Š”%20๋•์ž…๋‹ˆ๋‹คโ€๋ผ๊ณ  ์š”์ฒญํ•˜๋Š” ์ƒํƒœ์˜€๋‹ค.

ํ•˜์ง€๋งŒ ์„œ๋ฒ„์—์„œ ์˜ฌ๋ฐ”๋ฅธ URL์ธ์ง€ ์ฒดํฌํ•˜๋Š” ๊ณผ์ •์—์„œ DB์— ์ €์žฅ๋˜์–ด ์žˆ๋Š” url ์ •๋ณด์—์„œ โ€œ์•ˆ๋…•ํ•˜์„ธ์š” ์ €๋Š” ๋•์ž…๋‹ˆ๋‹ค.โ€์™€

์ผ์น˜ํ•˜๋Š”์ง€ ๊ฒ€์ฆํ•˜๋Š” ๋กœ์ง์—์„œ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํŒ๋‹จํ•ด์„œ ๋ฐœ์ƒํ•œ ์ด์Šˆ์˜€๋‹ค.

๋ฐœ์ƒ ์ด์œ 

DB์—์„œ ๊ฐ€์ ธ์˜จ url์˜ ๊ณต๋ฐฑ์„ ์—†์• ๊ณ  ์‹ค์ œ๋กœ ๋„˜์–ด์˜จ url๊ณผ ๋น„๊ต๋ฅผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅด๋‹ค๊ณ  ์ธ์‹ํ•˜๋Š” ๊ฒฝ์šฐ์˜€๋‹ค.

URL๋กœ ๋„˜์–ด์˜จ ๊ฒƒ์„ location, DB์˜ ์ •๋ณด๋ฅผ ์ด๋ผ๊ณ  ์นญํ•˜๊ฒ ๋‹ค.

๐Ÿš€ Trial And Error


๊ณต๋ฐฑ ์ œ๊ฑฐํ•˜์ง€ ์•Š๊ณ  ๋น„๊ตํ•˜๊ธฐ

๋จผ์ € ๊ธฐ์กด ์ฝ”๋“œ์—์„œ ๋‘ ๊ฐ’ ๋ชจ๋‘ ์ธ์ฝ”๋”ฉ ํ›„ ์ •๊ทœ์‹์œผ๋กœ ๋ฌด์–ธ๊ฐ€๋ฅผ ํŒ๋‹จํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ์ธ์ฝ”๋”ฉ๊ณผ ์ •๊ทœ์‹์ด๋ผ๋Š”

๋ฐฉ์‹์„ ๋ฐ”๊ฟ€ ์ˆ˜๋Š” ์—†์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ url ๊ณต๋ฐฑ์„ ์ œ๊ฑฐํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•์„ ์„ ํƒํ–ˆ๋‹ค.

๋ฌธ์ œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋ฐœ์ƒํ–ˆ๋‹ค.

  • location๊ณผ url์„ ์ธ์ฝ”๋”ฉํ•˜๋Š” ํ•˜๋Š” ๊ณผ์ •์—์„œ ๊ณต๋ฐฑ์ด %20์ด ์•„๋‹Œ +๋กœ ์ธ์ฝ”๋”ฉ๋˜๋Š” ํ˜„์ƒ์ด์—ˆ๋‹ค.
    ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” java.net.URLEncoder.encode()๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค. ํ•ด๋‹น api๋Š” ๊ณต๋ฐฑ์„ +๋กœ ์ธ์ฝ”๋”ฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.
  • ์ธ์ฝ”๋”ฉ๋œ +๋ฅผ Pattern.compile.matcher.find๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ •๊ทœ์‹์œผ๋กœ ์ผ์น˜ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•œ๋‹ค.
  • ์ •๊ทœ์‹์œผ๋กœ +๋ฅผ ์ œ๋Œ€๋กœ ์ œ๋Œ€๋กœ ์ธ์‹ํ•˜์ง€ ๋ชปํ•ด์„œ ์™„์ „ํžˆ ๋™์ผํ•œ ๋ฌธ์ž์—ด์ธ๋ฐ๋„ findํ•˜์ง€ ๋ชปํ•œ๋‹ค๋Š” ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.

(์ฐธ๊ณ ๋กœ location ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ํ•œ๊ธ€๊ณผ ๊ณต๋ฐฑ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ์ธ์ฝ”๋”ฉ์ด ์ด๋ฏธ ๋˜์–ด ๋“ค์–ด์˜จ ์ƒํ™ฉ์ด๋ผ์„œ ๋””์ฝ”๋”ฉ ํ›„ ๋‹ค์‹œ ์ธ์ฝ”๋”ฉํ•˜๋Š” ๋ฐฉ์‹์ด์—ˆ๋‹ค.)

+๋ฅผ ์™œ ์ธ์‹ํ•˜์ง€ ๋ชปํ•˜๋Š”๊ฐ€

์ธ์‹ํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค. ์ •๊ทœ ํ‘œํ˜„์‹์—์„œ +ํ‘œํ˜„์‹์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

https://www.w3schools.com/jsref/jsref_obj_regexp.asp

์ธ์ฝ”๋”ฉ๋œ ๊ฒฐ๊ณผ๋ฅผ ๋จผ์ € ๋ณด๋ฉด location๊ณผ url ๋ชจ๋‘ โ€œ์•ˆ๋…•ํ•˜์„ธ์š”+์ €๋Š”+๋•์ด์ž…๋‹ˆ๋‹คโ€์ด๋‹ค.

ํ•˜์ง€๋งŒ n+ ํ‘œํ˜„์‹์ด๊ธฐ ๋•Œ๋ฌธ์— findํ•  ์ˆ˜ ์—†๋Š”๊ฒŒ ๋ฌธ์ œ์˜€๋‹ค.

๊ฒ€์ฆ์€ ์•„๋ž˜ ํ…Œ์ŠคํŠธ๋กœ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

@Test
void ๊ณต๋ฐฑ_ํ…Œ์ŠคํŠธ() {
  Matcher matcher1 = Pattern.compile("%20").matcher("%20");
  assertThat(matcher1.find()).isTrue();

  Matcher matcher2 = Pattern.compile("abc+").matcher("abc");
  assertThat(matcher2.find()).isTrue();

  Matcher matcher3 = Pattern.compile("abc+").matcher("fsdafsdfabc+c");
  assertThat(matcher3.find()).isTrue();

  Matcher matcher4 = Pattern.compile("abc+").matcher("bc+c");
  assertThat(matcher4.find()).isFalse();

  Matcher matcher5 = Pattern.compile("abc+d").matcher("abc+c");
  assertThat(matcher5.find()).isFalse();

    Matcher matcher6 = Pattern.compile("abc+d").matcher("abc");
  assertThat(matcher6.find()).isFalse();
}

๐Ÿš€ Solution


๊ณต๋ฐฑ์„ %20์œผ๋กœ ์ธ์ฝ”๋”ฉํ•˜๊ธฐ

๋จผ์ € URLEncoding Api๋กœ๋Š” ๋ถˆ๊ฐ€๋Šฅํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— spring์ด ์ œ๊ณตํ•˜๋Š” UriUtils๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•ด์„œ ์™„์ „ํžˆ ์ผ์น˜ํ•˜๋Š” ๋ฌธ์ž์—ด์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ผ์น˜ํ•˜๋„๋ก ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฆ‰, URLEncoder๋ฅผ ์ง€์–‘ํ•˜๊ณ  UriUtils๋ฅผ ์“ฐ๋„๋ก ํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค.

๋ฐ˜์‘ํ˜•
๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค!