개발/JSP & Servlet

[Tomcat] 톰캣서버 Servlet 한글 깨짐문제 해결 + 이유

YJ_Lee 2021. 9. 10. 20:51

한글이 깨지는 이유


  1. 서버에서 웹 문서를 전송할 때, 한글을 지원하지 않는 인코딩 방식을 사용할 경우
  2. 서버에서는 올바르게 인코딩 하였으나 브라우저가 다른 인코딩 방식으로 해석한 경우

 2번같은 경우는 브라우저가 문서를 받았을 때 해당 문서가 어떠한 방식의 인코딩을 사용하였는지 알지 못하기 때문에 브라우저가 자의적으로 해석하였기 때문이다.

 따라서 페이지의 인코딩 방식과 패킷 헤더에 해당 인코딩 방식을 명시함으로써 문제를 해결할 수 있다.

 

 해결방법으로는 몇 가지가 있는데 첫번쨰로는 인코딩 방식을 web.xml파일에서 지정해줄 수 있다. 하지만 일반적으로 하나의 웹 서버는 다수의 페이지가 공유하기 때문에 서버 설정파일은 잘 건드리지 않는다.

 

 두 번째로는 각각의 페이지마다 인코딩 방식을 정해주는 것이다.

response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");

* response는 HttpServletResponse의 인스턴스이다.

 setCharacterEncoding()은 페이지의 인코딩 방식을 설정한 것이고 setContentType()은 패킷의 response 헤더에 인코딩 방식을 명시하여 브라우저가 해당 인코딩 방식을 이용하여 해석할 수 있도록 한 것이다.

text/html은 해당 컨텐츠가 html 문서임을 알리는 것이다. 본인이 리턴하는 컨텐츠 타입을 명시해 주면 된다.

해당 구문이 없으면 브라우저가 자의적으로 해석(보통 text로 해석) 하여 html 태그가 동작하지 않을 수 있다.

 * Rest API 를 구현한 경우에는 컨텐츠 타입이 application/json 이다.

 

세 번째로는 각각의 파일에 명시하지 않고 서블릿 필터를 이용하는 것이다.

public class EncodingFilter implements Filter {
	public void doFilter(ServletRequest request, ServletResponse response
					, FilterChain chain) throws IOException, ServletException {
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html; charset=UTF-8");
		chain.doFilter(request, response);	
	}

	public void destroy() {
	}

	public void init(FilterConfig filterConfig) throws ServletException {
	}
}

 

 FilterChain.doFilter()는 필터와 필터, 필터와 서블릿을 연결하는 역할을 한다. 해당 구문이 실행되면 다음 필터나 다음 서블릿을 호출하므로 해당 구문 위쪽에 적힌 내용은 서블릿 실행 전에 작업되고, 아랫쪽에 적힌 내용은 서블릿 실행 후에 작업된다.

 인코딩 방식은 서블릿 실행 전에 정해 주어야 하므로 doFiler() 위쪽에 적어 주었다.

 

*request.setCharacterEncoding()

 서버에 get 혹은 post 요청이 올 때, 해당 데이터를 어떠한 인코딩 방식으로 해석할 것인지 정한다.