JFreeChart 是經典 Java 圖表庫,整合到 Web 應用需解決依賴傳遞、Servlet 註冊、類路徑隔離三大問題。本文以 JFreeChart 1.0.10 + Tomcat 5.0 + JDK 1.4 為例,梳理生產環境可用的配置全流程,新版本 (JFreeChart 1.5.x、Tomcat 9/10、JDK 11/17) 同理可循。
| JAR 包 | 版本示例 | 用途 | Maven 坐標 (現代專案) |
|---|---|---|---|
| jfreechart | 1.0.10 | 核心圖表繪製 | org.jfree:jfreechart:1.5.4 |
| jcommon | 1.0.13 | 基礎工具庫 | org.jfree:jcommon:1.0.24 |
| iText | 2.1.1 | PDF 輸出 (可選) | com.lowagie:itext:2.1.7 (舊版) 或 com.itextpdf:itext7-core |
| gnujaxp | - | XML 解析 (舊版依賴) | 現代 JDK 內置,通常無需額外引入 |
手動部署: 將上述 JAR 放入專案 WEB-INF/lib/ (推薦,實現應用級隔離) 或 Tomcat 共享 common/lib/ (易發生版本衝突,不推薦)。
# Linux/Unix ~/.bashrc 或 /etc/profile
export JAVA_HOME=/usr/java/jdk1.4.2_11
export CATALINA_HOME=/opt/tomcat5
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$CATALINA_HOME/common/lib/servlet-api.jar:$CATALINA_HOME/common/lib/jsp-api.jar:$JAVA_HOME/lib/jfreechart-1.0.10.jar
# Windows 系統環境變量
JAVA_HOME=C:\Java\jdk1.4.2_11
CATALINA_HOME=C:\Tomcat5
CLASSPATH=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;%CATALINA_HOME%\common\lib\servlet-api.jar;%CATALINA_HOME%\common\lib\jsp-api.jar;%JAVA_HOME%\lib\jfreechart-1.0.10.jar
Path 追加 %JAVA_HOME%\bin;%CATALINA_HOME%\bin
注意: 生產環境極不建議依賴系統 CLASSPATH,應由構建工具 (Maven/Gradle) 打包進 WAR 的 WEB-INF/lib,由 WebAppClassLoader 隔離加載。
JFreeChart 提供 org.jfree.chart.servlet.DisplayChart 用於在 Web 頁面直接輸出圖片 (PNG/JPEG)。
<servlet>
<servlet-name>DisplayChart</servlet-name>
<servlet-class>org.jfree.chart.servlet.DisplayChart</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DisplayChart</servlet-name>
<url-pattern>/servlet/DisplayChart</url-pattern>
</servlet-mapping>
用法: JSP/HTML 中 <img src="/servlet/DisplayChart?chart=...&width=500&height=300" />,參數詳見 JFreeChart 文檔 ChartUtilities。
// pom.xml
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.5.4</version>
</dependency>
// Controller
@RestController
@RequestMapping("/api/charts")
public class ChartController {
@GetMapping("/bar")
public void barChart(HttpServletResponse response) throws IOException {
// 1. 建立數據集
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(10, "Series1", "Jan");
dataset.addValue(20, "Series1", "Feb");
// 2. 創建圖表
JFreeChart chart = ChartFactory.createBarChart("Title", "Category", "Value", dataset, PlotOrientation.VERTICAL, true, true, false);
// 3. 輸出 PNG
response.setContentType("image/png");
ChartUtils.writeChartAsPNG(response.getOutputStream(), chart, 600, 400);
}
}
優勢:無需額外 Servlet 註冊、依賴傳遞自動化、單元測試容易、容器化部署無感知。
| 現象 | 原因 | 解決 |
|---|---|---|
| NoClassDefFoundError: org/jfree/chart/servlet/DisplayChart | jfreechart.jar 未在 WEB-INF/lib 或共享 lib | 檢查 WAR 包內結構、Maven 依賴範圍為 compile |
| 圖表中文顯示方塊/亂碼 | 缺少中文字體或未設置字體 | 代碼設置 chart.getTitle().setFont(new Font("Microsoft YaHei", Font.BOLD, 16))、Linux 安裝 fonts-wqy-zenhei |
| 輸出圖片模糊/尺寸異常 | writeChartAsPNG 寬高參數與前端 img 寬高不匹配 | 前端 CSS 控制顯示尺寸、後端生成高 DPI (1.5x/2x) 圖片 |
| 內存洩漏 (大量圖表生成) | 未釋放 Graphics2D、BufferedImage 資源 | 使用 try-with-resources、ChartUtils.writeChartAsPNG 內部已處理、避免長期持有 Chart 對象 |
JFreeChart 整合核心在於依賴隔離 (WEB-INF/lib)、Servlet 正確註冊、中文字體顯式設置。新專案請直接採用 Spring Boot + Maven/Gradle 管理依賴,棄用系統 CLASSPATH 與手動 web.xml 註冊,擁抱現代化構建與部署流程。