HttpServletRequest (請求) 與 HttpServletResponse (響應) 是 Servlet 規範中處理 HTTP 交互的核心介面。本文系統整理兩大介面的高頻方法分類速查表、編碼/亂碼處理、輸入輸出流使用、Header/Cookie/Session 操作、轉發/重定向/錯誤頁 等實戰場景,附代碼範例與避坑指南。
| 分類 | 方法 | 說明 |
|---|---|---|
| 參數獲取 | getParameter(String name) | 單值參數 (表單/查詢字串) |
getParameterValues(String name) | 多值參數 (checkbox/多選) | |
getParameterMap() | 所有參數 Map<String, String[]> | |
getParameterNames() | 所有參數名 Enumeration | |
getQueryString() | 原始查詢字串 (a=1&b=2) | |
getReader() / getInputStream() | 請求體原始流 (JSON/XML) | |
| Header/元信息 | getHeader(String name) | 單個 Header |
getHeaders(String name) | 多值 Header | |
getHeaderNames() | 所有 Header 名 | |
getMethod() | HTTP 方法 (GET/POST...) | |
getContentType() | Content-Type | |
| 路徑/URL | getRequestURI() | /context/path/to/resource |
getRequestURL() | 完整 URL (含協議/域名/埠) | |
getContextPath() | /context | |
getServletPath() | /path/to/servlet | |
getPathInfo() | /extra/path (通配映射時) | |
| 客戶端/伺服器信息 | getRemoteAddr() | 客戶端 IP (注意代理) |
getRemoteHost() | 客戶端主機名 | |
getServerName() | 伺服器主機名 | |
getServerPort() | 伺服器埠 | |
| 屬性作用域 | getAttribute(String) | Request 屬性 |
setAttribute(String, Object) | 設置 Request 屬性 | |
getSession() / getSession(boolean) | 獲取/創建 Session | |
getAttributeNames() | 所有屬性名 | |
| 編碼/國際化 | getCharacterEncoding() | 請求編碼 |
setCharacterEncoding(String) | 設置請求編碼 (必須在讀參數前) | |
getLocale() / getLocales() | 客戶端 Locale |
| 分類 | 方法 | 說明 |
|---|---|---|
| 狀態碼 | setStatus(int) | 設置狀態碼 (不觸發錯誤頁) |
sendError(int) | 發送錯誤頁 (觸發 web.xml error-page) | |
sendError(int, String) | 發送錯誤頁 + 訊息 | |
sendRedirect(String) | 302 重定向 (瀏覽器地址欄變化) | |
setIntHeader / setDateHeader | 設置數值/日期 Header | |
| Header 操作 | setHeader(String, String) | 設置單值 Header (覆蓋) |
addHeader(String, String) | 新增多值 Header | |
containsHeader(String) | 判斷 Header 是否已設置 | |
setContentType(String) | Content-Type + charset | |
setContentLengthLong(long) | Content-Length (大檔必設) | |
| 輸出流 | getWriter() | 字符流 PrintWriter (用編碼) |
getOutputStream() | 位元組流 ServletOutputStream | |
flushBuffer() / reset() / resetBuffer() | 緩衝區控制 | |
isCommitted() | 響應是否已提交 | |
| Cookie/Session | addCookie(Cookie) | 寫入 Cookie |
encodeURL / encodeRedirectURL | URL 重寫 (支援無 Cookie 會話) | |
getSession() | 獲取 Session (同上) | |
setLocale(Locale) | 設置響應 Locale |
@WebFilter("/*")
public class EncodingFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
chain.doFilter(req, resp);
}
}
String json;
try (BufferedReader reader = req.getReader()) {
json = reader.lines().collect(Collectors.joining());
}
UserDTO dto = new ObjectMapper().readValue(json, UserDTO.class);
resp.reset();
resp.setContentType("application/octet-stream");
resp.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedName);
resp.setContentLengthLong(file.length());
resp.setHeader("Accept-Ranges", "bytes");
try (InputStream in = new FileInputStream(file);
OutputStream out = resp.getOutputStream()) {
byte[] buf = new byte[8192];
int len;
while ((len = in.read(buf)) != -1) out.write(buf, 0, len);
}
// 轉發: 伺服器內部跳轉, 請求對象不變, 瀏覽器地址不變
req.getRequestDispatcher("/WEB-INF/views/success.jsp").forward(req, resp);
// 重定向: 瀏覽器發起新請求, 請求對象丟失, 地址欄變化
resp.sendRedirect(req.getContextPath() + "/login.html");
public String getRealIp(HttpServletRequest req) {
String ip = req.getHeader("X-Forwarded-For");
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = req.getHeader("X-Real-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = req.getRemoteAddr();
}
// 多層代理取第一個非 unknown
return ip.split(",")[0].trim();
}
IllegalStateException。isCommitted() == true 後再 setHeader/sendRedirect/forward 拋 IllegalStateException。cookie.setPath("/")、setSecure(true) (HTTPS)、setHttpOnly(true) (防 XSS)。getSession() 等同 getSession(true),JSP 頁面預設會創建 Session,若無需 Session 頁面加 <%@ page session="false" %>。熟練掌握 HttpServletRequest 的「參數、Header、路徑、屬性、編碼」五大分類與 HttpServletResponse 的「狀態、Header、流、Cookie」四大分類,配合 Filter 統一編碼、工具類封裝 JSON/文件/真實 IP,即能高效處理 95% Servlet 交互場景。記住編碼在最前、流互斥、提交後不可寫、大檔設長度四大鐵律,避開 80% 低級錯誤。