首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Servlet 輸出圖片流時 Cookie 失效:響應提交順序導致 Header 被擋

     編輯:程式設計疑難解答

問題代碼

public String yzm() throws Exception {
    response.setCharacterEncoding("UTF-8");
    Object[] obj = verification.RandomCount();
    OutputStream out = response.getOutputStream(); // 1. 獲取輸出流
    ImageIO.write((BufferedImage) obj[1], "JPEG", out); // 2. 寫圖片
    Cookie cookie = new Cookie("captcha", obj[0].toString()); // 3. 建 Cookie
    cookie.setMaxAge(3600);
    cookie.setPath("/");
    response.addCookie(cookie); // 4. 添加 Cookie
    out.flush();
    return null;
}

現象:註釋掉 ImageIO.write 時 Cookie 正常;寫圖片後 Cookie 消失。

根因:響應提交機制

  • 調用 response.getOutputStream() 或 getWriter() 後,**響應體**已開啟。
  • Servlet 容器在首次寫入響應體數據時,會**隱式提交響應頭**(Status Line + Headers,含 Set-Cookie)。
  • 之後再調用 response.addCookie(),**頭部已發送,無法再添加**,Cookie 丟失。

解決方案:先設置 Cookie,再獲取輸出流

public String yzm() throws Exception {
    response.setCharacterEncoding("UTF-8");
    Object[] obj = verification.RandomCount();

    // 1. 先處理所有 Header 相關操作
    Cookie cookie = new Cookie("captcha", obj[0].toString());
    cookie.setMaxAge(3600);
    cookie.setPath("/");
    response.addCookie(cookie); // 必須在 getOutputStream() 之前

    // 2. 再獲取輸出流寫圖片
    OutputStream out = response.getOutputStream();
    ImageIO.write((BufferedImage) obj[1], "JPEG", out);
    out.flush();
    return null;
}

原則總結

  1. **Header 操作(setHeader、addCookie、setContentType、setStatus 等)必須在獲取 OutputStream/Writer 之前完成。**
  2. 若不確定順序,可在方法開頭集中處理所有 Header,再進行流操作。
  3. 同理,Forward/Redirect 也屬 Header 操作,需在流操作前調用。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved