pageEncoding="UTF-8"、Tomcat URIEncoding="UTF-8" 均已設置new String(bytes, "ISO-8859-1", "GBK") 轉碼無效核心原因:JDBC 驅動在建立連接時未正確聲明字符集,導致驅動按默認編碼 (通常 ISO-8859-1) 解析數據庫返回的字節流。後續在 Java 層轉碼屬於「二次轉碼」,原始字節流已損壞,無法恢復。
關鍵差異:MySQL/PostgreSQL 等現代驅動支持連接參數 characterEncoding 自動轉碼;Sybase jConnect 驅動必須在 JDBC URL 中顯式指定 charset 參數,否則不進行任何轉換。
在 Sybase 中執行:
sp_configure "default character set id"
-- 或
select @@charset
常見值:
cp850 (Western European)eucgb (GB2312/EUC-CN)utf8 (UTF-8)gbk (GBK)
// 模板
jdbc:sybase:Tds:hostname:port/dbname?charset=DB_CHARSET&jconnect_version=VERSION
// 實例 1:數據庫字符集為 eucgb (GB2312),jConnect 7+
String url = "jdbc:sybase:Tds:192.168.1.100:5000/mydb?charset=eucgb&jconnect_version=7";
// 實例 2:數據庫字符集為 cp850,jConnect 6
String url = "jdbc:sybase:Tds:sybase-host:4100/proddb?charset=cp850&jconnect_version=6";
// 實例 3:數據庫已為 UTF-8
String url = "jdbc:sybase:Tds:localhost:5000/testdb?charset=utf8&jconnect_version=7";
關鍵參數說明:
charset:必須與數據庫實際字符集一致,驅動據此將接收字節流解碼為 Java Unicode 字符串jconnect_version:匹配驅動版本 (4/5/6/7),影響協議細節<%@ page import="java.sql.*" %>
<%
String url = "jdbc:sybase:Tds:192.168.1.100:5000/mydb?charset=eucgb&jconnect_version=7";
String user = "sa";
String pwd = "password";
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
Class.forName("com.sybase.jdbc4.jdbc.SybDriver"); // jConnect 7
// Class.forName("com.sybase.jdbc3.jdbc.SybDriver"); // jConnect 6
conn = DriverManager.getConnection(url, user, pwd);
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT name, description FROM products WHERE id = 1");
if (rs.next()) {
// 直接使用 getString(),驅動已按 charset 正確解碼
String name = rs.getString("name");
String desc = rs.getString("description");
out.println("產品: " + name + "
描述: " + desc);
}
} catch (Exception e) {
e.printStackTrace();
out.println("錯誤: " + e.getMessage());
} finally {
// 標準資源關閉
try { if (rs != null) rs.close(); } catch (Exception ignore) {}
try { if (stmt != null) stmt.close(); } catch (Exception ignore) {}
try { if (conn != null) conn.close(); } catch (Exception ignore) {}
}
%>
jconnect_version 與 sybdriver.jar 版本匹配 (jConnect 6/7/16/17 常見)-Djconnect.debug=true 觀察字符集協商過程| 錯誤做法 | 為何無效 |
|---|---|
Java 層 new String(rs.getBytes("col"), "ISO-8859-1", "GBK") | 驅動已按錯誤編碼將字節解碼為 char[],再 getBytes 丟失原始字節 |
| 只設置 JSP pageEncoding / Tomcat URIEncoding | 只影響 HTTP 響應編碼,不影響 JDBC 驅動解碼 |
| 連接池配置未傳遞 charset 參數 | Druid/HikariCP url 屬性必須包含完整 JDBC URL 含 charset |
| 假設數據庫為 UTF-8 實為 GBK | charset 參數與實際不符,解碼錯誤產生亂碼 |
?charset=實際DB字符集 (如 eucgb、cp850、utf8)jconnect_version 與驅動 jar 版本一致rs.getString() 即得正確中文