ejyoo's 개발 노트

[JSP] 한글 깨짐 처리방법 및 문자 인코딩 본문

BackEnd/JSP_Servlet

[JSP] 한글 깨짐 처리방법 및 문자 인코딩

ejyoovV 2021. 5. 8. 13:31

상황 : 텍스트 출력 시 한글이 깨졌음

 

웹 개발 시 GET / POST 로 처리하는 로직에서

화면을 출력했더니 한글이 깨지는 현상을 발견하였다.

이런 상황이 종종 있을 것 같아 그에대한 인코딩에 대한 개념과 처리방법을 정리하고자 한다.

환경 : [웹서버 : 톰캣 / 웹 페이지 기본 인코딩 : UTF-8]

 

HTTP 통신 방법에 대해 먼저 알아야 할 것!

http 통신 시 문자 인코딩에 대해 알아야 한다.

클라이언트(브라우저) ▶ request(get/post) ▶ 웹서버 (was: tomcat) ▶response(get/post) ▶클라이언트(브라우저)

과정을 거친다.

 

이 모든 과정을 하나의 인코딩을 할 수 없다.

위의 과정 순간 순간마다 문자 인코딩 문제가 발생한다.

 

1. Request : URL 창에 직접 입력

 - HTTP 표준에서 GET 방식으로 전달하는 파라미터에 대한 인코딩의 규약은 존재하지 않는다. 
  그러므로 브라우저마다, 웹 컨테이너 마다 다르다.
  즉, Request를 송신할 때 인코딩 방식과 Request를 수신할 때 디코딩 방식이 다르면 글자는 깨진다.
  그러므로 모든 웹 페이지를 구성함에 있어서 인코딩을 신경써야 한다.

 

 - 브라우저에 따라 인코딩 방식이 다르다.
  인터넷 익스플로러는 MS949 를 사용하고 크롬은 UTF-8 을 사용한다. 
  그러므로 서버에 영향을 받지 않는 URL 창에서 직접 입력할 경우, 브라우저의 기본 인코딩 형태에 따라 문자가 인코딩되어 웹 컨테이너로 전달된다.

 

 

JSP 에서의 인코딩 설정

1. 웹 페이지 내 GET, POST 메서드

- 웹 페이지에 입력한 내용은 웹서버의 영향을 받는다.

  웹 서버에서 지정한 값으로 인코딩 값을 결정할 수 있다.

  JSP 같은 경우 아래와 같은 코드를 통해 contentType을 결정한다.

- 현재 사용할 페이지의가 UTF-8을 사용한다는 것을 브라우저에게 알려준다. ( 응답 관련 인코딩 )

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

 

웹 서버 인코딩 설정(서블릿에서 GET 방식으로 호출하는 경우)

1. 웹서버 / 웹 컨테이너

 - 웹 컨테이너에 따라서 인코딩 방식은 다르다.

 - 톰캣 8 이후부터는 UTF-8을 기본으로 사용하지만, 톰캣 7은 ISO-8859-1을 기본값으로 사용한다.

  따라서 톰캣의 Server.xml에 아래와 같이 설정을 해야 한다.

 

HTTPServletRequest 객체의 setCharacterEncoding() 메서드의 경우

브라우저가 보낸 HTTP 요청 메시지의 BODY 부분을 인코딩해주는 메서드이다.

즉 GET 방식의 요청인 경우 HTTP 메시지의 Body 부분이 없기 때문에 웹 서버 인코딩 설정이 필요하다.

GET 방식 요청의 경우,

데이터는 URI에 쿼리스트링 형태로 담겨져 오기 때문에

컨테이너에서 URI를 인코딩 하여 받는 설정을 해야한다.

URIEncoding="utf-8"

 

GET 방식 내 URL 인코딩 설정

1. Response

 - 클라이언트에 데이터를 전달할 때 마찬가지로 인코딩을 해야한다. 

  특히 GET방식을 통해 인코딩을 할 경우 URL의 값이 브라우저마다 다를 수 있다.

  그러므로 반드시 인코딩을 해야하며, 자바는 해당 과정을 위해 클래스와 메서드를 제공한다.

URL 용 Encoder를 클래스로 따로 빼서 구성하였고, 혹시 Decoder가 필요한 경우, 아래 코드를 사용한다.

Exception은 throw 하지 않고 에러 문구를 Log4j를 사용하여 출력하였다.

String value = URLEncoder.encode("안녕", "utf-8");
response.sendRedirect("/content/sayhello.jsp?name="+value);
package ejyoo.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

import org.apache.log4j.Logger;

public class EncoderDecoder {
	private static final Logger EXCEPTION_LOGGER = Logger.getLogger(EncoderDecoder.class);
	
	public static String textEncoder(String str) {
		String encodeTxt = "";
		try {
			encodeTxt = URLEncoder.encode(str, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			EXCEPTION_LOGGER.error(e.getMessage());
		}
		return encodeTxt;
	}
	
	public static String textDecoder(String str) {
		String decodeTxt = "";
		try {
			decodeTxt = URLDecoder.decode(str, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			EXCEPTION_LOGGER.error(e.getMessage());
		}
		return decodeTxt;
	}
}

 

서블릿에서 인코딩 설정(서블릿에서 POST 방식으로 호출하는 경우)

HttpServletRequest 객체의 setCharacterEncoding() 메서드를 예를 들었을 때,

클라이언트가 보낸 HTTP 요청 메시지의 BODY 부분을 인코딩해주는 메서드이다.

 

post 방식인 경우 HTTP 요청 메시지의 BODY 부분으로 들어가기 때문에,

response 와 request에 대해 한글을 표현할 수 있는 인코딩으로 세팅한다.

주의할 점은 

response.getWriter() 나 request.getParameter() 메서드 사용 전에 세팅을 해야한다.

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

 

 

모든 과정은 인코딩 문제가 존재한다.

서블릿(jsp 마다) request와 response에 대한 encoding의 값을 선언하고

페이지 마다 contentType을 선언하며,

get 방식으로 그 값을 url로 입력하면 URLEncoder와 URLDecoder를 사용해야 한다.

 

 

삽질한 내역

1. JSP에서 char-set, 이클립스 인코딩 설정 모두 완료함.

2. 깨진 파라미터 값을 URL.Encoder, URL.Decoder 를 사용해봄.

3. 서블릿 내 Request, Response 인코딩 설정함 => 완료.