배경설명
- 인코딩 방식이 다른 송/수신 서버간 String length 처리 방식 차이로 인한 한글 문자열 깨짐 현상
- 인코딩에 따른 한글 byte length 차이점 이해하기
구분 | String length 처리 방식 | 인코딩 방식 | 인코딩 특징 | 한글 1글자 처리 |
---|
송신(요청) | length | UTF-8 | 다양한 언어와 문자 지원. 가장 보편적! | 3 byte |
수신(응답) | byte | EUC-KR | 한국어를 처리하기 위함. | 2 byte |
로직상세
- 수신
- 항목 1개 당 byte는 12
고정
- fixed length 12 byte n개 항목 read
- 송신
- EUC-KR 기준 12 byte 이하의 한글 포함 문자열 입력
가변
- fixed length 12 byte 맞추기 위한 rpad ' ' 문자열 설정
해결방안
- 송신 : 수신 인코딩 방식인 EUC-KR 기준 byte length가 12인 문자열 전달
샘플소스
1. EUC-KR 기준 byte length 구하기
- getBytes() : 문자열을 특정 인코딩으로 byte 배열로 변환
public static int getByteLength(String iStr, String encodeFlag) throws UnsupportedEncodingException {
return iStr.getBytes(encodeFlag).length;
}
- EUC-KR 한글 1글자 = 2 byte 확인
@Test
void getByteLegnthEUCKRTest() throws UnsupportedEncodingException {
String iStr = "한글입력";
assertEquals(StringUtil.getByteLength(iStr, "EUC_KR"), 8);
}
2. EUC-KR 기준 rpad 문자열 반환
public static String rpad(String iStr, int mByteLen, char pChar, String encodeFlag) throws UnsupportedEncodingException {
byte[] encodeByteArr = iStr.getBytes(encodeFlag);
StringBuilder psb = new StringBuilder(iStr);
for (int i = 0; i < mByteLen - encodeByteArr.length; i++) {
psb.append(pChar);
}
return psb.toString();
}
- [JUnit] EUC-KR 기준 byte length가 무조건 mByteLen (12) 인 rpad 문자열 생성 확인
@Test
void rpadByByteForEUCKRTest() throws UnsupportedEncodingException {
String iStr = "한글입력";
mByteLen = 12;
String oStr = StringUtil.rpad(iStr, mByteLen, ' ', "EUC_KR");
assertEquals(StringUtil.getByteLength(oStr, "EUC_KR"), mByteLen);
}
결론
- 서버마다 인코딩 방식은 다르다.
- 수신 쪽 인코딩 방식에 맞춰 요청 파라미터를 설정하자!
참고
- URLEncode.encode() : 문자열 인코딩은 동일하지만, URL query 문자열 값 인코딩하는데 사용!
- get 방식을 통한 파라미터 전달 시, 값을 안전하게 전달하기 위한 목적