瀏覽器請求圖片時,HTTP 響應的 Content-Type 為 image/jpeg 等 MIME 類型,主體為二進位圖片資料。Servlet 只需設定正確 Header,將記憶體中繪製完成的圖片編碼寫入 response.getOutputStream(),即可實現動態圖片輸出(驗證碼、統計圖表、水印等)。
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics2D g = bi.createGraphics();g.dispose(); bi.flush(); 釋放資源。ImageIO.write(bi, "JPEG", response.getOutputStream());(JDK 9+ 建議用標準 API,避免依賴 com.sun.image.codec.jpeg 內部類)。package com.demo.web;
import javax.imageio.ImageIO;
import javax.servlet.*;
import javax.servlet.http.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
public class DynamicImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("image/jpeg"); // 關鍵:告訴瀏覽器這是 JPEG
int w = 200, h = 80;
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
// 1. 背景漸層
g.setPaint(new GradientPaint(0, 0, Color.WHITE, w, h, Color.LIGHT_GRAY));
g.fillRect(0, 0, w, h);
// 2. 干擾線
g.setColor(Color.GRAY);
for (int i = 0; i < 10; i++) {
g.drawLine((int)(Math.random()*w), (int)(Math.random()*h),
(int)(Math.random()*w), (int)(Math.random()*h));
}
// 3. 文字
g.setFont(new Font("微軟正黑體", Font.BOLD, 28));
g.setColor(Color.BLUE);
g.drawString("Dynamic", 20, 50);
g.dispose();
bi.flush();
// 4. 標準 API 輸出
ImageIO.write(bi, "JPEG", resp.getOutputStream());
}
}
<servlet>
<servlet-name>DynamicImage</servlet-name>
<servlet-class>com.demo.web.DynamicImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DynamicImage</servlet-name>
<url-pattern>/dynamic.jpg</url-pattern>
</servlet-mapping>
HTML:<img src="dynamic.jpg" alt="動態圖片">
resp.setHeader("Cache-Control","no-store");;統計圖可加 ETag/Last-Modified 支援條件請求。wqy-zenhei),否則中文會顯示方塊。