본문 바로가기
웹 프로그래밍/Servlet & JSP

Servlet 한글 깨짐 오류, 한글 처리

by kgvovc 2021. 3. 11.
반응형

한글 처리

이번 절에서는 클라이언트가 전송한 문자열에 한글이 있을 때 깨지지 않고 올바르게 표현하기 위한 방법을 알아보겠습니다. 먼저, 폼에서 한글이 입력되었을 때 어떤 결과가 나오는지 예제를 통해 살펴보겠습니다.

 

WebContent에 "name.html"이라는 이름으로 새로운 HTML 파일을 만들고, 다음과 같은 코드를 작성합니다.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>이름 입력</title>
</head>
<body>
	<form action="queryTest3" method="post">
		이름 : <input type="text" name="name">
		<input type="submit" value="전송">
	</form>
</body>
</html>

 

<meta charset="UTF-8">는 현재 HTML 파일이 저장될 때 사용할 인코딩 문자코드를 설정합니다. charset에 "UTF-8"로 지정했기 때문에 현재 HTML 파일은 UTF-8 문자코드를 사용해 인코딩 처리됩니다.

 

com.edu.test에 새로운 클래스 파일을 만들고, 이름을 "QueryTest3Servlet.java"으로 입력합니다. 그리고 다음과 같은 코드를 작성합니다.

package com.edu.test;

import java.io.*;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;


@WebServlet("/queryTest3")
public class QueryTest3Servlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html;charset=UTF-8");
		PrintWriter out = resp.getWriter();
		out.print("<html><head><title>Query 문자열 테스트</title></head>");
		out.print("<body>");
		out.print("<h1>GET 방식으로 요청되었습니다.</h1>");
		
		String name = req.getParameter("name");
		out.print("이름: " + name + "<br/>");
		
		out.println("</body></html>");
		out.close();
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html;charset=UTF-8");
		PrintWriter out = resp.getWriter();
		out.print("<html><head><title>Query 문자열 테스트</title></head>");
		out.print("<body>");
		out.print("<h1>POST 방식으로 요청되었습니다.</h1>");
		
		String name = req.getParameter("name");
		out.print("이름: " + name + "<br/>");
		
		out.println("</body></html>");
		out.close();
	}
}

 

 

name.html을 실행하고 이름 입력 폼에 한글을 입력한 다음, 전송을 클릭합니다.

 

 

 

[실행 결과]

 

 

POST 방식으로 요청했기 때문에 doPost() 메소드가 실행되었습니다. 그런데 이름에 입력한 "홍길동" 문자열이 깨져서 출력됩니다.

 

깨진 한글을 복원하는 방법은 GET과 POST 방식이 다릅니다. GET 방식은 요청정보 헤더의 URI에, POST 방식은 요청정보 몸체에 포함되어 전달되기 때문입니다. 지금부터 요청방식에 따라 한글로 전달된 질의 문자열을 처리하는 방법을 알아보겠습니다.

 

POST 방식 한글 처리

POST 방식은 서블릿 API에서 한글 코드 변환을 해주는 메소드를 제공하고 있어서 메소드를 사용해 간단하게 한글을 처리할 수 있습니다. POST 방식에서 한글 처리를 해주는 메소드는 HttpServletRequest의 상위 객체인 ServletRequest에서 제공하는 setCharacterEncoding() 메소드입니다.

 

void setCharacterEncoding(String env) throws UnsupportedEncodingException

 

setCharacterEncoding() 메소드는 인자값으로 지정된 문자코드를 사용하여 클라이언트가 전달한 요청정보 몸체에 있는 문자열들을 인코딩해주는 메소드입니다. 클라이언트로부터 질의 문자열이 전달된 후 서블릿이 실행될 때 setCharacterEncoding() 메소드로 인코딩 작업을 처리한 후 getParameter() 메소드로 추출하여 사용합니다.

 

예제를 통해 메소드를 사용해보겠습니다. QueryTest3Servlet.java 소스의 doPost() 메소드를 아래와 같이 수정합니다.

~생략~
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	resp.setContentType("text/html;charset=UTF-8");
	PrintWriter out = resp.getWriter();
	out.print("<html><head><title>Query 문자열 테스트</title></head>");
	out.print("<body>");
	out.print("<h1>POST 방식으로 요청되었습니다.</h1>");
	
	req.setCharacterEncoding("UTF-8");
	String name = req.getParameter("name");
	out.print("이름: " + name + "<br/>");
	
	out.println("</body></html>");
	out.close();
}
~생략~

 

name.html을 실행해 다시 "홍길동"을 입력하면,

 

[실행 결과]

 

 

한글이 깨지지 않고 정상 출력됨을 확인할 수 있습니다.

 

 

GET 방식 한글 처리

이번에는 한글 질의 문자열을 GET 방식으로 전달했을 경우를 살펴보겠습니다. GET 방식으로 전달된 질의 문자열은 요청정보 헤더의 URI에 포함되어 전달됩니다. setCharacterEncoding() 메소드는 요청정보의 몸체에 있는 데이터들만 인코딩해주기 때문에 GET 방식은 사용할 수 없습니다. GET 방식으로 전달된 질의 문자열들은 URI에 포함되어 전달되기 때문에 URI에 대해 인코딩 처리 작업을 해야 합니다.

 

GET 방식으로 전달되는 질의 문자열들의 인코딩 작업을 할 때는 다음과 같은 질문에 답이 무엇인지 명확히 하고 작업합니다.

 

  • 클라이언트가 입력하는 질의 문자열의 인코딩 문자코드는 무엇인가?
  • 서버에서 URI를 인코딩하는 문자코드는 무엇인가?

 

1) 클라이언트가 입력하는 질의 문자열의 인코딩 문자코드는 무엇인가?

클라이언트가 입력한 문자열들을 인코딩 처리하는 방법은 두 가지입니다. 소스에서 직접 인코딩 문자코드를 지정해주는 방법과 이클립스에서 인코딩 문자를 지정하는 방법입니다.

 

소스에서 직접 인코딩 문자코드를 지정해주는 방법

<head>와 </head>사이에 <meta charset="UTF-8"> 태그처럼 사용하고자 하는 문자코드를 지정하는 것입니다.

 

이클립스에서 소스의 인코딩 문자코드를 지정하는 방법

이클립스에서 [Window] -> [Preferences] -> [Web] -> [HTML Files]를 선택한 다음, 'Encoding'에서 원하는 문자코드를 지정합니다. 다른 형식(CSS, JSP)의 파일도 같은 방법으로 인코딩을 지정합니다.

 

또는 여러 타입으로 된 문서의 인코딩 문자를 한번에 설정하고자 한다면, 이클립스에서 [Window] -> [Preferences] -> [General] -> [Content Types] -> [Text]를 선택한 후, 'Default encoding' 값을 원하는 문자코드로 입력한 다음, <Update>와 <OK>를 클릭합니다.

 

 

2) 서버에서 URI를 인코딩하는 문자코드는 무엇인가?

클라이언트로부터 전달된 URI 문자열의 인코딩 작업은 서버에서 처리해줍니다. 서버마다 기본적으로 URI의 인코딩 문자코드가 정해져 있으며 톰캣 8 버전에서는 UTF-8 문자코드가 기본값으로 적용됩니다. 만일 서버의 URI 인코딩 처리 문자코드를 지정하고 싶다면, 서버의 환경설정 파일 중 server.xml 파일에 인코딩 문자코드를 설정해줍니다.

 

server.xml 파일의 내용 중 <Connector> 태그를 찾아 다음처럼 URIEncoding="UTF-8" 속성을 <Connector> 태그에 추가합니다.

~생략~
<Connector connectionTimeout="머시기"
		   port="포트번호"
		   protocol="프로토콜"
		   redirectPort="포트번호"
		   URIEncoding="UTF-8" />
~생략~
반응형

댓글