Redirect 시 한글 파라미터가 깨지는 문제

이번에 토이 프로젝트를 하면서 발견한 문제인데
Spring controller에서 redirect:로 redirection 응답 시 파라미터 값에 한글이 들어가 있을 경우 ?? 로 파라미터 값이 전달되는 문제를 발견했다.

간단하지만 웹에 대한 기초적인 지식이기 때문에 정리할 겸 포스팅한다.


테스트에 사용할 코드는 간단하게 아래와 같이 만들었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class RedirectionController {

@GetMapping("/redirect")
public String redirect(String name) {
return "redirect:/hello?name=" + name; // /hello 로 redirection 응답
}

@GetMapping("/hello")
public String hello(String name, Model model) {
model.addAttribute("name", name); // name을 model에 담아 view로 보낸다.

return "hello";
}
}
1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello</h1>
<h2 th:text="${name}"></h2> <!-- model에 담긴 name attribute를 출력 -->
</body>
</html>

서버 실행 후 http://localhost:8080/hello?name=세계 로 접속을 하면 아래와 같이 한글 깨짐 없이 정상적으로 예상하는 결과가 나온다.

하지만 http://localhost:8080/redirect?name=세계 로 접속하면 아래와 같이
http://localhost:8080/hello?name=?? 로 redirection 되어 원하는 결과가 나오지 않는다.

왜 이런 결과가 나오는 것일까?
왜냐하면 redirect URL에 name 파라미터를 인코딩 없이 그냥 사용했기 때문이다.

1
return "redirect:/hello?name=" + name;

URL에는 ASCII가 아닌 문자를 사용할 수 없다. 그래서 ASCII가 아닌 파라미터의 경우 percent encoding을 해줘야 우리가 원하는 결과를 얻을 수 있다.

그러면 처음에 접속한 http://localhost:8080/hello?name=세계는 어떻게 redirect와 달리 파라미터가 깨지지 않았을까?
그건 브라우저가 encoding을 해서 요청을 보내기 때문이다.
브라우저 주소창에 http://localhost:8080/hello?name=세계을 치고 주소창에 있는 주소를 복사하여 텍스트 에디터에 붙여넣기하면 아래와 같은 값을 볼 수 있다.

1
http://localhost:8080/hello?name=%EC%84%B8%EA%B3%84

문제의 원인은 파악했으니 코드로 이를 어떻게 해결할까?
해답은 아래와 같이 URLEncoder를 사용하면 된다.

1
2
3
4
5
6
@GetMapping("/redirect")
public String redirect(String name) throws UnsupportedEncodingException {
String encodedParam = URLEncoder.encode(name, "UTF-8");

return "redirect:/hello?name=" + encodedParam;
}

코드를 변경한 후 다시 서버를 올리고 http://localhost:8080/redirect?name=세계 로 재접속하면 아래 같이 우리가 원하는 결과를 볼 수 있다.


관련 질문은 아래에 있으니 참고하면 좋을 것 같다. (아마 한국분이 하신 질문인듯)

https://stackoverflow.com/questions/21477986/url-encoding-in-google-chrome

Share