CharSet이 EUC-KR인 서버가 있습니다. 

클라이언트에서는 jQuery를 이용하여 Form을 다루려고 합니다.


myForm이라는 데이터를 전송하는 폼이 있습니다.

그 폼의 input 벨류들을 모두 jQuery의 .serialize()를 통해서 

직렬화하고(문자열로 만들고) 보내면 좋을것 같습니다.


그래서 아래처럼 함수를 작성했습니다.


var myForm = jQuery('#myForm');

jQuery.ajax({
type : myForm.attr('method'),
url : '/reimaginer/FormManager.ym',
data : myForm.serialize(),
success : function (res) {
if(res === 'SUCCESS') {
alert('등록되었습니다.');
} else {
alert('등록이 실패하였습니다.')
}
}
});



영어로 테스트 해봤는데 잘 됩니다. 오 좋다~ 하고 있는데, 한국어로도 테스트해봅니다.
그런데 깨집니다...


문제의 원인에 대해서 고민해보니, jQuery는 기본적으로 charSet이 UTF-8이라는게 기억납니다.
그럼이제 UTF-8로 인코딩된 언어를 어떻게 안 깨뜨리고 잘 가져올지 고민해봅니다.

예전에 모바일 프로젝트할때, 모바일 클라이언트는 charSet이 UTF-8이었습니다. 
그래서 UTF-8로 두번 인코딩하고, 서버에서 한번 자동으로 디코딩 된 후,
다시 한번, decodeUri를 통해서 한글을 가져온 것이 생각이 납니다.

인터넷을 뒤적거리다보니 비슷한 방법이 나옵니다.
.serialize() 하면 UTF-8로 한번 인코딩된 문자열이 나옵니다.
만약 폼에서 전송하려는 데이터가 '사과' 라는 문자열이라면,

'%EC%82%AC%EA%B3%BC' 

이런 놈이 반환되죠. 여기서 우리는 한번 더 인코딩합니다.
% 문자를 인코딩된 문자인 '%25'로 한번 더 바꿔주는 겁니다.
(= % 를 %25로 바꿔주기만 해도 한글이 깨지지 않고 넘어갑니다. )

"%25EC%2582%25AC%25EA%25B3%25BC" 이렇게요.

코드는 다음과 같습니다.


var myForm = jQuery('#myForm');

jQuery.ajax({
type : myForm.attr('method'),
url : '/reimaginer/FormManager.ym',
data : myForm.serialize().replace(/%/g, '%25'),
//data : encodeURI(myForm.serialize()), 위, 아래 두가지 방법 모두 같은 결과를 반환한다.
success : function (res) {
if(res === 'SUCCESS') {
alert('등록되었습니다.');
} else {
alert('등록이 실패하였습니다.')
}
}
})
;


그럼 서버 측에서는 어떻게 받아야 할까요.


String decodedData = URLDecoder.decode(encodedData, "UTF-8");


한번은 자동으로 decode되니까 '%EC%82%AC%EA%B3%BC' 이 문자열을 받았겠죠.

한번만 더 디코드 해줍니다.

'사과'

이제 이 한글을 잘 사용하면 됩니다!


javascript 에서 제공하는 encodeURI()와 encodeURIComponent() 함수는 기본적으로 UTF-8으로 인코딩을 합니다


이를 Query로 하여 jsp 페이지에 넘겨서

request.getParameter() 함수로 받고서 아무 의심없이 URLDecoder.decode() 함수를 사용했습니다

당연히 UTF-8으로 decode를 했지요

하지만 계속해서 한글이 깨져있습니다;;;

계속 원인을 찾던 중

tomcat이 Query를 미리 서버에 지정된 기본 문자셋으로 디코딩을 해버린다는 사실을 알았습니다

즉, request.getParameter()로 받은 결과가 인코딩 된 문자열이 아닌 이미 디코딩 된 문자열이었지요

즉, 기대한 값은 %EC%95%88%EB%85%95%ED%95%98%EC%84%B8%EC%9A%94 과 같은 모양의 문자열인데

이미 저 값은 URLDeocder.decode( 문자열, 서버 기본 문자셋 ) 함수로 한번 디코딩 된 결과 같이 나온다는 거에요

많은 경우 서버 기본 문자셋이 MS-949 등이기 때문에 UTF-8으로 인코딩 된 값을 잘못 디코딩한 것이죠

잘못 디코딩된 녀석을 다시 디코딩 해봤자 한글이 깨져있는 것은 당연한 것이지요...



1. 해결 방법으로는 서버 기본 문자셋을 UTF-8으로 바꿔버리는 방법과...



2. 데이터의 양이 늘어나지만 encodeURI() 또는 encodeURIComponent() 의 결과를 한번 더 인코딩 해버리는 방법도 있습니다

encodeURIComponent( encodeURIComponent( plainText ) );  // 이렇게요

그리고 jsp에서는 URLDecoder.decode() 함수를 한번만 ( 한번은 자동으로 디코딩을 수행하기 때문에 ) 호출하면 됩니다

이렇게 될 경우 tomcat이 자동으로 디코딩한 결과는 원래 기대 값인 인코딩 된 값

%EC%95%88%EB%85%95%ED%95%98%EC%84%B8%EC%9A%94 과 같은 모양의 문자열

이 되고, 이를 URLDecoder.decode() 함수로 제대로 디코딩 해주기 때문에 원하는 결과 값이 나오게 됩니다


출처 : http://allinfo.tistory.com/1095

'Server > Encoding' 카테고리의 다른 글

[Ajax] euc-kr 서버 한글 깨짐 해결  (0) 2016.12.08
[WAS] Tomcat server.xml utf 8 encoding  (0) 2015.01.08
[Encode] Spring POST/GET URI Encoding  (0) 2014.10.12



<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" />


스프링에서의 POST/GET 한글처리

springmvc.egloos.com/513986

스프링을 사용하면서 얻을 수 있는 가장 큰 이점 중 하나는 매번 개발자들이 골칫거리였던 한글처리가 매우 용이하고 간편하다게 변했다는 점이다. 물론 한글 뿐만이 아니라 UTF-8에서 지원하는 모든 국제어 사용이 자유로우며 POST/GET방식 양쪽 다 처리가 능수능란하게 처리가 가능하다. 이게 정녕 스프링을 이용해서 얻는 이점인지, 아니면 필자가 몰랐던 한글 처리 방법인지는 잘 모르겠지만 최소한 스프링을 모르기 전 서블릿과 JSP로 무식하게 MVC 코드를 짰던 순간과 비교하면 정말 행복에 겨워 눈물이 날 지경이다.

먼저 EUC-KR로 문서를 인코딩할 바에야 UTF-8로 문서를 인코딩하는 것이 나으므로 이클립스에서 모든 문서가 UTF-8로 생성될 수 있도록 설정을 바꿔주도록 하자.

Window > Preferences > General > Workspace 
하단 좌측 Text file encoding = Other: UTF-8 
변경

이 설정을 하면 현재까지 작성했던 모든 문서가 UTF-8로 인코딩되며 앞으로 작성될 문서들도 UTF-8로 인코딩되어 작성되게 된다. 만약 이 설명을 하기 전에 한글로 작성한 파일이 있다면 미리 백업해두길 바란다. UTF-8로 인코딩이 변경되면 기존에 있던 한글이 깨져서 나올 수도 있다.

첫번째로 POST방식의 한글 처리를 해결해보도록 하자. 사실 필자의 부끄러운 과거에는 GET방식의 한글 처리법을 할 줄 몰라 대부분의 데이터 전송을 POST로만 전송했던 과거가 있었다. GET에 비해 POST 방식은 ContentType만 설정해도 간단히 인코딩할 수 있었기 때문에 필자는 보안을 핑계 삼아 꾸역꾸역 데이터를 POST으로만 보냈었는데 지금 생각해보면 참 바보같은 짓이었다. 덕분에 사용자들은 즐겨찾기의 즐거움과 네비게이터의 활용을 만끽하지 못했고 말이다 :(


POST에서 한글처리

스프링에서 POST 전송방식의 UTF-8 인코딩은 정말 간단하다. web.xml에 스프링이 제공하는 CharacterEncodingFilter를 걸어주면 끝이다.

<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> 
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

CharacterEncodingFilter는 Http상에서 주고받는 데이터의 헤더값을 UTF-8로 인코딩 해줌으로서 다국어 지원을 보장해준다. 매핑할 때 위와 같이 모든 URL에 인코딩 될 수 있도록 적용해주었는지 다시 한번 확인해보자. 제대로 확인하였다면 이제 우리는 앞으로 헤더값으로 주고받는 데이터들에 대해서는 한글의 사용을 보장받을 수 있게 되었다.


GET에서 한글처리

GET에서 한글 처리는 POST와는 조금 다르다. 왜냐하면 POST에서는 헤더값으로 통해 데이터를 주고받기 때문에 서블릿에서 어느 정도 컨트롤이 가능하지만 GET은 URL에 직접 데이터를 추가하여 전송하는 방식이기 서블릿의 영역 밖에 존재한다. 그러므로 GET을 통해 한글을 데이터를 받고자 할 때는 서버에서 직접 URL을 UTF-8로 인코딩할 수 있게끔 설정해 주어야 한다.

이클립스에서 제공하는 실행도구를 이용해 톰캣을 기동시키고 있다면 다음과 같은 위치에서 Server.xml을 찾을 수 있다.

만약 실행도구로 톰캣을 실행시키지 않는다면 직접 [CATALINA_HOME]\conf 경로로 찾아가 Server.xml 파일을 열어주도록 하자. 우리가 Server.xml에서 추가해줘야 할 부분은 다음과 같다.

<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"/>

위의 두 요소에서 굵은 글씨 부분을 추가해주면 된다. 위에는 8080포트에서 들어오는 URI요청을 인코딩해주고 아래는 8009포트에서 보내지는 요청을 인코딩해준다. 보통 8080 포트를 많이 사용하므로 위에만 추가해줘도 되지만 만약을 대비하여 아래의 커넥터에도 인코딩 속성을 추가해주도록 하자.

이제 모든 설정이 끝났다. 정말 쉽고 간단하지 않은가? 과거 서블릿에서 HttpServletRequest와 HttpServletResponse에 일일이 인코딩 설정을 달아주고 유니코드 메서드까지 만들어가며 힘겹게 GET을 인코딩하던 시절은 이제 머나먼 옛날 일이다.

출처 : http://springmvc.egloos.com/viewer/513986

+ Recent posts