首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Servlet 進階:HttpServlet 深度解析請求、Header、Cookie 與 Session

     編輯:Java 程式設計入門

HttpServlet 是 Servlet 開發的核心類別,封裝 HTTP 協定細節,提供豐富 API 存取請求行、Header、參數、Cookie、Session。本文透過 SnoopServlet 完整展示如何提取並呈現所有 HTTP 請求資訊,是除錯、監控、安全審計的利器。

完整程式碼:SnoopServlet

package com.example;

import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.*;
import java.util.*;

@WebServlet("/snoop")
public class SnoopServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        
        resp.setContentType("text/plain;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        
        out.println("=== Snoop Servlet ===\n");
        
        // 1. Servlet 初始化參數
        out.println("--- Servlet 初始化參數 ---");
        Enumeration<String> initParams = getInitParameterNames();
        while (initParams.hasMoreElements()) {
            String key = initParams.nextElement();
            out.println("  " + key + " = " + getInitParameter(key));
        }
        out.println();
        
        // 2. Context 初始化參數
        out.println("--- Context 初始化參數 ---");
        ServletContext ctx = getServletContext();
        Enumeration<String> ctxParams = ctx.getInitParameterNames();
        while (ctxParams.hasMoreElements()) {
            String key = ctxParams.nextElement();
            out.println("  " + key + " = " + ctx.getInitParameter(key));
        }
        out.println();
        
        // 3. Context 屬性 (應用級共享資料)
        out.println("--- Context 屬性 ---");
        Enumeration<String> ctxAttrs = ctx.getAttributeNames();
        while (ctxAttrs.hasMoreElements()) {
            String key = ctxAttrs.nextElement();
            out.println("  " + key + " = " + ctx.getAttribute(key));
        }
        out.println();
        
        // 4. Request 屬性 (請求級傳遞資料)
        out.println("--- Request 屬性 ---");
        Enumeration<String> reqAttrs = req.getAttributeNames();
        while (reqAttrs.hasMoreElements()) {
            String key = reqAttrs.nextElement();
            out.println("  " + key + " = " + req.getAttribute(key));
        }
        out.println();
        
        // 5. 基本請求資訊
        out.println("--- 基本請求資訊 ---");
        out.println("Servlet 名稱: " + getServletName());
        out.println("協定: " + req.getProtocol());
        out.println("Scheme: " + req.getScheme());
        out.println("伺服器名稱: " + req.getServerName());
        out.println("伺服器埠: " + req.getServerPort());
        out.println("伺服器資訊: " + ctx.getServerInfo());
        out.println("客戶端 IP: " + req.getRemoteAddr());
        out.println("客戶端主機: " + req.getRemoteHost());
        out.println("字元編碼: " + req.getCharacterEncoding());
        out.println("內容長度: " + req.getContentLength());
        out.println("內容類型: " + req.getContentType());
        out.println("Locale: " + req.getLocale());
        out.println("預設回應緩衝: " + resp.getBufferSize());
        out.println();
        
        // 6. 請求參數 (查詢字串 / 表單資料)
        out.println("--- 請求參數 ---");
        Enumeration<String> paramNames = req.getParameterNames();
        while (paramNames.hasMoreElements()) {
            String key = paramNames.nextElement();
            String[] values = req.getParameterValues(key);
            out.print("  " + key + " = ");
            for (int i = 0; i < values.length; i++) {
                out.print(values[i] + (i < values.length - 1 ? ", " : ""));
            }
            out.println();
        }
        out.println();
        
        // 7. 請求 Header
        out.println("--- 請求 Header ---");
        Enumeration<String> headerNames = req.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = headerNames.nextElement();
            out.println("  " + key + ": " + req.getHeader(key));
        }
        out.println();
        
        // 8. Cookie
        out.println("--- Cookie ---");
        Cookie[] cookies = req.getCookies();
        if (cookies != null) {
            for (Cookie c : cookies) {
                out.println("  " + c.getName() + " = " + c.getValue()
                    + " [Domain:" + c.getDomain() + ", Path:" + c.getPath()
                    + ", MaxAge:" + c.getMaxAge() + ", Secure:" + c.getSecure() + "]");
            }
        } else {
            out.println("  (無 Cookie)");
        }
        out.println();
        
        // 9. 安全與認證資訊
        out.println("--- 安全與認證 ---");
        out.println("是否 HTTPS: " + req.isSecure());
        out.println("認證類型: " + req.getAuthType());
        out.println("HTTP 方法: " + req.getMethod());
        out.println("遠端使用者: " + req.getRemoteUser());
        out.println();
        
        // 10. URL 解析細節
        out.println("--- URL 解析 ---");
        out.println("請求 URI: " + req.getRequestURI());
        out.println("Context Path: " + req.getContextPath());
        out.println("Servlet Path: " + req.getServletPath());
        out.println("Path Info: " + req.getPathInfo());
        out.println("Path Translated: " + req.getPathTranslated());
        out.println("Query String: " + req.getQueryString());
        out.println();
        
        // 11. Session 完整資訊
        out.println("--- Session ---");
        HttpSession session = req.getSession(false); // 不自動建立
        if (session != null) {
            out.println("請求 Session ID: " + req.getRequestedSessionId());
            out.println("當前 Session ID: " + session.getId());
            out.println("建立時間: " + new Date(session.getCreationTime()));
            out.println("最後存取: " + new Date(session.getLastAccessedTime()));
            out.println("最大閒置秒數: " + session.getMaxInactiveInterval());
            out.println("Session 屬性:");
            Enumeration<String> sessAttrs = session.getAttributeNames();
            while (sessAttrs.hasMoreElements()) {
                String key = sessAttrs.nextElement();
                out.println("  " + key + " = " + session.getAttribute(key));
            }
        } else {
            out.println("  (無有效 Session)");
        }
    }
}

核心 API 分類速查

類別核心方法用途
初始化參數getInitParameterNames(), getInitParameter(String)部署時靜態配置 (web.xml/@WebServlet initParams)
Context 參數/屬性getServletContext() → getInitParameter*, getAttribute*應用級共享配置與物件 (資料源、快取、全域設定)
Request 參數getParameterNames(), getParameterValues(String), getParameterMap()查詢字串、表單提交、multipart (需 @MultipartConfig)
Request HeadergetHeaderNames(), getHeader(String), getHeaders(String)User-Agent、Referer、Authorization、Content-Type 等
CookiegetCookies() → Cookie[]客戶端狀態管理、追蹤、偏好設定
URL 解析getRequestURI(), getContextPath(), getServletPath(), getPathInfo(), getQueryString()路由、RESTful 參數提取、重寫
SessiongetSession(boolean), getAttribute/putAttribute, invalidate()伺服器端會話狀態、購物車、登入憑證

實戰應用場景

  • 除錯神器:部署在測試環境,快速檢視實際請求內容、Header、Session 狀態。
  • 安全審計:記錄 RemoteAddr、User-Agent、Referer、Authorization 偵測異常存取。
  • API 相容性測試:驗證客戶端送出的參數名稱、格式、編碼是否符合契約。
  • 效能基準:觀察 Content-Length、Header 數量、Cookie 大小評估頻寬開銷。

部署提示

在 web.xml 或 @WebServlet 設定初始化參數:

@WebServlet(
    urlPatterns = "/snoop",
    initParams = {
        @WebInitParam(name = "adminEmail", value = "admin@example.com"),
        @WebInitParam(name = "maxRows", value = "100")
    }
)

Context 參數在 web.xml:

<context-param>
    <param-name>appName</param-name>
    <param-value>MyApp</param-value>
</context-param>

掌握 HttpServletRequest 完整 API,等於掌握 HTTP 請求的每一個細節。搭配 Filter/Interceptor 可在控制器前統一記錄、驗證、轉換請求資料,構建健壯的 Web 應用基礎設施。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved