FIF's 코딩팩토리

[Spring] UTF-8 한글 깨짐 본문

Back-End/Spring(스프링)

[Spring] UTF-8 한글 깨짐

FIF 2019. 8. 22. 09:19
반응형

Spring UTF8 한글 깨짐

 

오류 내용

spring 프로젝트에서 한글이 깨짐

  • 한글이 깨지는 이유
    • 보통 브라우저 —> 서버 —> DBMS 로 같은 내용의 한글이 서비스 처리를 하는 단계에서 매번 다른 문자코드를 사용하여 재표현되기 때문이다.
  • 한글을 올바르게 표현하는 방법
    • GET와 POST 방식이 다르다.
    • GET
      • 3 이용
      • 데이터가 GET방식에서는 요청정보 Header의 URI에 포함되어 전달된다.
      • 서블릿의 영역 밖에 존재한다.
      • URI에 대해 인코딩 처리 작업
    • POST
      • 1 + 2 이용
      • 데이터가 POST방식에서는 요청정보 Body에 포함되어 전달된다.
      • 서블릿에서 어느 정도 컨트롤이 가능하다.

 

해결 방법

1. [POST 방식] 스프링 웹 프로젝트 web.xml에 utf-8 설정

	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter
		</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
  • Spring Web Project - POST 방식에서의 한글 깨짐 해결 방법
  • 역할
    • 브라우저 —> 요청정보 Body 데이터 —UTF8 인코딩—> Java 단에서의 데이터 처리
    • CharacterEncodingFilter
      • HTTP상에서 주고 받는 데이터의 헤더값을 UTF-8로 인코딩
    • Servlet에서의 request.setCharacterEncoding("utf-8");
      • POST로 인코딩 데이터를 받는 Servlet에서의 request.setCharacterEncoding("utf-8"); 처리와 동일한 기능을 수행한다.
      • 즉, 이 Filter를 설정하면 POST 요청을 보내는(Submit) 모든 Controller(Servlet) 마다 request.setCharacterEncoding("utf-8"); 내용을 추가하지 않아도 된다.
    • 또한 DB에서 불러올 한글 데이터들의 한글 깨짐 현상을 해결한다.
  • 사용
    • 해당 filter를 매핑할 때 모든 URL에 대해 인코딩될 수 있도록 /*와 같이 url-pattern을 설정한다.
    • 주의!) Spring Security 설정이 있는 경우,
      한글 필터 설정이 springSecurityFilterChain 앞에 위치해야 한다.

 

 

2. [POST 방식] .jsp 파일에 utf-8 설정

 

  • Spring Web Project - POST 방식에서의 한글 깨짐 해결 방법
  • 역할
    • 응답정보 Body 데이터(JSP 내의 Java 코드 + HTML) —UTF8 인코딩—> 브라우저
      • JSP의 인코딩 방식이 무엇인지 알 수 있게 선언하는 것
      • jsp 파일에서의 한글 깨짐이 해결된다.
    • Servlet에서의 response.setContentType("text/html;charset=UTF-8");
      • Servlet에서의 response.setContentType("text/html;charset=UTF-8"); 처리와 유사한 기능을 수행한다.
      • Servlet/JSP 단에서의 설정 방벙의 차이점은
        아래의 참고2) dispatcher-servlet.xml에서의 설정과 차이점을 참고하자.
  • 참고1) 왜 UTF-8 이 두 번 선언이 되어 있을까
    • contentType: 서버에서 생성될 HTML의 charset에 대한 정보
    • pageEncoding: JSP 내의 Java 코드에 대한 charset에 대한 정보
  • 참고2) dispatcher-servlet.xml에서의 설정과 차이점
	<!-- dispatcher-servlet.xml에서의 설정 (Servlet/JSP 단에서의 설정) 예시 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/" />
		<property name="suffix" value=".jsp" />
		<property name="contentType" value="text/html; charset=UTF-8" />
	</bean>

Servlet/JSP 단에서의 설정

dispatcher-servlet.xml에서의 설정은 Servlet 단에서의 설정을 의미한다.

.jsp 파일 상의 page 설정은 JSP 단에서의 설정을 의미한다.

Servlet/JSP 단에서의 설정 방법의 차이

JSP 디폴트 contentType: ISO-8859-1

아무리 Servlet에서 response.setContentType 결정해서 보내더라도 .jsp page 자체의 contentType은 jsp spec에서 결정되므로 직접 기술해주지 않으면 ISO-8859-1로 설정된다.

Servlet 단에서의 설정은 JSP가 아닌 텍스트 리턴 시에만 이용된다.

따라서, 직접 .jsp page에 기술하는 것이 좋다.

 

 

POST 방식에서의 한글 처리 추가 설명 (Servlet에서 한글처리)

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    // ... 생략
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /* 요청정보 Body에 있는 문자열들을 인자값으로 지정한 문자코드로 인코딩한다. */
        request.setCharacterEncoding("UTF-8");
        
        //getParameter는 중복되지 않고 유일하게 하나만 넘어올 떄 사용된다.
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        /* 응답정보 문자열들을 인자값으로 지정한 문자코드로 인코딩한다.  */
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        String htmlResponse = "<html>";
        htmlResponse += "<head><title>Query 문자열 한글 테스트</title></head>";
        htmlResponse += "<h2> your name is " + username + "<br/>";
        htmlResponse += "<h2> your password is " + password + "<br/>";

        out.println(htmlResponse);
    }
}
  • request.setCharacterEncoding() 메서드 역할
    • 브라우저 —> 요청정보 Body 데이터 —UTF8 인코딩—> Java 단에서의 데이터 처리
      • 1번 [POST 방식] 스프링 웹 프로젝트 web.xml에 utf-8 설정 과정에 해당한다.
    • 한글 처리를 해주는 메서드는 HttpServletRequest의 상위 객체인 ServletRequest에서 제공하는 setCharacterEncoding() 메서드이다.
    • setCharacterEncoding(“UTF-8”) 메서드는 클라이언트가 전달한 요청정보 Body에 있는 데이터(문자열)들을 메서드 인자값으로 지정한 문자코드(UTF-8)로 인코딩해준다.
  • request.setCharacterEncoding() 메서드 사용
    • Java 단에서 데이터를 받아오기 전((getParameter() 메서드)에 인코딩을 처리한다.
    • 즉, getParameter() 메서드 위에서 사용해야 한다.request.setCharacterEncoding("UTF-8"); request.getParameter("param")
  • response.setContentType() 메서드 역할
    • 응답정보 Body 데이터(Text 데이터) —UTF8 인코딩—> 브라우저
      • 2번 [POST 방식] .jsp 파일에 utf-8 설정 과정에 해당한다.
    • response.setContentType(“text/html;charset=UTF-8”) 메서드는 클라이언트에 전달할 응답정보 Body에 있는 데이터(문자열)들을 메서드 인자값으로 지정한 문자코드(UTF-8)로 인코딩해준다.
  • response.setContentType() 메서드 사용
    • html을 출력하는 메서드 위에서 사용해야 한다.
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String htmlResponse = "<html><head><title>한글 테스트</title></head></html>";
out.println(htmlResponse);

 

 

3. [GET 방식] Tomcat 서버의 환경 설정 파일 server.xml에 utf-8 설정

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8" />
  • Web Project - GET 방식에서의 한글 깨짐 해결 방법
    • GET 방식으로 전달된 질의 문자열들은 URI에 포함되어 전달되기 때문에 URI에 대해 인코딩 처리 작업을 해야한다.
    • 서버마다 기본적으로 URI 인코딩 문자코드가 정해져 있으며 톰캣8 버전에서는 UTF-8 문자코드가 기본값으로 적용된다.
  • Servers(아파치 톰캣)의 해당 프로젝트 config 폴더 > server.xml 파일 > URIEncoding="UTF-8"property를 추가한다.
    • 서버에서 직접 URI를 UTF-8로 인코딩하는 과정

 

 

4. .html 파일에 utf-8 설정

<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>Home</title>
</head>
  • head 태그 영역을 위와 같이 설정한다.
    • 최신 IDE(통합 개발 환경)를 사용한다면 기본적인 인코딩 방식은 UTF-8로 설정이 되어있다.
    • 하지만 Windows 운영체제는 기본 인코딩 값으로 여전히 euc-kr방식을 사용하기 때문에, 해당 페이지의 인코딩 방식(utf-8)이 무엇인지 브라우저가 알 수 있게 선언해야 한다.
  • 사용
    • HTML5의 경우
      • <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">를 head 태그 안에 삽입
    • XHTML의 경우
      • <meta charset="utf-8">를 head 태그 안에 삽입

 

 

관련된 Post

References

 

 

 

 

 

 

반응형
Comments