Servlet 3.0 引入註解配置,徹底擺脫繁瑣的 web.xml 映射。本文系統講解 @WebServlet 全屬性用法、多 URL 映射、啟動加載順序、異步處理配置及與 web.xml 混合部署的優先級規則。
@WebServlet("/hello.do")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.getWriter().write("Hello, Annotation!");
}
}
<servlet-mapping><url-pattern>/hello.do</url-pattern></servlet-mapping>;servlet-name(全限定名),可通過 name 屬性覆蓋。| 屬性 | 類型 | 默認值 | 說明 |
|---|---|---|---|
value / urlPatterns | String[] | {} | 核心屬性,URL 模式數組,至少一個。兩屬性二選一,value 為簡寫。 |
name | String | 全限定類名 | Servlet 邏輯名,用於 ServletContext.getServletRegistration() 查找。 |
loadOnStartup | int | -1 | >0:容器啟動時實例化並 init();數值越小優先級越高。-1:首次請求時懶加載。 |
initParams | @WebInitParam[] | {} | 初始化參數,等價 <init-param>,getInitParameter() 獲取。 |
asyncSupported | boolean | false | 啟用 Servlet 3.0 異步處理(req.startAsync()),長輪詢/推送必開。 |
description | String | "" | 文檔描述,管理控制台顯示。 |
displayName | String | "" | 工具顯示名。 |
smallIcon/largeIcon | String | "" | 圖標路徑,極少用。 |
@WebServlet(
name = "OrderServlet",
urlPatterns = { "/order/create", "/order/query", "/order/*" },
loadOnStartup = 1,
initParams = {
@WebInitParam(name = "pageSize", value = "20"),
@WebInitParam(name = "maxRetries", value = "3")
},
asyncSupported = true,
description = "訂單核心處理 Servlet"
)
public class OrderServlet extends HttpServlet {
private int pageSize;
private int maxRetries;
@Override
public void init() throws ServletException {
pageSize = Integer.parseInt(getInitParameter("pageSize"));
maxRetries = Integer.parseInt(getInitParameter("maxRetries"));
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 異步處理示例
AsyncContext ctx = req.startAsync();
ctx.start(() -> {
try { Thread.sleep(2000); } catch (InterruptedException ignored) {}
ctx.getResponse().getWriter().write("Async Done");
ctx.complete();
});
}
}
/order/create 只匹配該路徑;/order/* 匹配 /order/ 及其子路徑;*.do、*.action 匹配對應後綴;/ 匹配所有未被其他模式匹配的請求(靜態資源通常由 DefaultServlet 處理)。優先級:精確 > 最長前綴 > 擴展名 > 默認。
web.xml 中的 <servlet>、<servlet-mapping> 覆蓋 註解配置;web.xml 中 <absolute-ordering> 可控制掃描順序,甚至禁用註解掃描(<absolute-ordering/> 空標籤);| 現象 | 原因 | 修正 |
|---|---|---|
| 404 Not Found | URL 模式寫錯(如漏了 / 前綴) | 模式必須以 / 或 *. 開頭 |
| 啟動報錯 "Duplicate servlet mapping" | 多個 Servlet 註解映射同一 URL | 檢查 urlPatterns 去重 |
| initParams 讀取為 null | 拼寫錯誤或未在 init() 中調用 getInitParameter | 大小寫敏感,建議常量定義 key |
| 異步超時 / IllegalStateException | 未設置 asyncSupported=true 或未調用 ctx.complete() | 必開屬性,確保所有分支 complete |
| loadOnStartup 不生效 | 值 ≤ 0 或容器不支持(極少見) | 設置 ≥ 1 的整數 |
loadOnStartup=1 預熱,減少首請求延遲;asyncSupported=true + 線程池異步執行;initParams 僅放極少數不變常量,業務配置走 Spring @Value/Nacos;name 使用業務語義(如 OrderCreateServlet),便於監控與管理;https://host:port/manager/html (Tomcat Manager) 查看 Servlet 註冊表,確認映射生效。「註解配置讓 Servlet 成為真正的 POJO 組件,零 XML 侵入。善用loadOnStartup預熱、asyncSupported異步,能讓 Servlet 容器在高併發下跑出非阻塞的性能。」