在無圖形介面的 Linux/Unix 伺服器上運行 Java 圖形程式(如 JFreeChart、JFreeReport)輸出中文,常面臨 HeadlessException、缺少中文字體、DISPLAY 異常等問題。本文提供從 JVM 參數、字體安裝、font.properties 配置到編碼編譯的完整解決方案。
-Djava.awt.headless=true,但會導致 Frame.getImage() 拋出 HeadlessException,建議改用 ImageBuffer。gb2312 編譯,運行時讀入為 ISO-8859-1/UTF-8,後續轉換無效。java -Djava.awt.headless=true -jar your-app.jar
字體檔(.ttf)來源:
C:\Windows\Fonts(如 simsun.ttc、simhei.ttf)。/usr/lib/X11/fonts/TrueType/。複製到 $JRE_HOME/lib/fonts/ 目錄。
cd $JRE_HOME/lib/fonts
ttmkfdir > fonts.dir
檢查 fonts.dir 第一行數字為字體總數,後續每行格式:檔案名 -foundry-family-weight-...。
JVM 搜尋順序:font.properties.zh_CN.GBK → font.properties.zh → font.properties。建議直接修改 font.properties。
參考 font.properties.zh.Turbo(TurboLinux 附帶),將其中無效字體條目(如 -tlc-song-medium-r-normal--*-%d-*-*-c-*-gbk-0)替換為 fonts.dir 中實際存在的字體編碼。
關鍵映射範例:
serif.plain.0=simsun.ttc -misc-sim sun-medium-r-normal--0-0-0-0-p-0-iso10646-1
javac -encoding gb2312 YourClass.java
或在 Ant/Maven 中設定 encoding="gb2312",確保字串常量正確編碼。
Servlet/JSP 輸出字元流,由客戶端瀏覽器渲染字體,只需設定:
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
圖形程式則在伺服器端生成圖片,必須解決伺服器端字體問題,複雜度高得多。
ttmkfdir 執行後必須檢查 fonts.dir 內容與 font.properties 引用一致。