Solaris 預設系統編碼為 ASCII,導致 `String.getBytes()` 使用平台預設編碼處理字串,中文高位元組遺失。
<%@ page contentType="text/html;charset=gb2312" %>
<%
String str = request.getParameter("i");
// byte[] b = str.getBytes("iso-8859-1"); // 正確
byte[] b = str.getBytes(); // 錯誤:使用平台預設 ASCII
out.println(new String(b, "gb2312"));
%>
| 方案 | 優點 | 缺點 |
|---|---|---|
| 修改 JDBC 驅動程式 | 徹底解決資料層編碼 | 維護成本高、升級困難 |
| 中文編碼為 7-bit (Hex/Unicode Escape) | 實作簡單、不動驅動程式 | 字串長度倍增、SQL 工具無法直接編輯、特定字元可能衝突 SQL 語法 |
public String encode() {
try {
StringBuffer sb = new StringBuffer();
byte[] bytes = m_enc.isEmpty() ? m_str.getBytes() : m_str.getBytes(m_enc);
for (int i = 0; i < bytes.length; i++) {
char ch = Character.forDigit((bytes[i] >> 4) & 0xF, 16);
sb.append(ch);
ch = Character.forDigit(bytes[i] & 0xF, 16);
sb.append(ch);
}
return sb.toString();
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unsupported encoding type.");
}
}
public void decode(String encodedStr) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < encodedStr.length(); i += 2) {
sb.append((char) Integer.parseInt(encodedStr.substring(i, i+2), 16));
}
m_str = new uniString(sb.toString(), "iso-8859-1").cvt(m_enc);
}