@WebServlet、@WebFilter、@WebListener、@WebInitParam、@MultipartConfig 等,使 web.xml 成為可選。web-fragment.xml (放在 JAR 的 META-INF/) 實現模組化擴充,無需修改主應用,類似 Struts2 外掛機制。Servlet 執行緒完整持有請求:預處理 → **阻塞等待業務 (DB/RPC)** → 產生回應 → 結束。高併發下執行緒耗盡。
@WebServlet(urlPatterns="/async", asyncSupported=true)
public class AsyncDemoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("進入 Servlet:" + new Date()); out.flush();
// 1. 啟動非同步上下文
AsyncContext ctx = req.startAsync();
// 2. 委派給獨立執行緒處理業務
new Thread(new AsyncExecutor(ctx)).start();
out.println("Servlet 主執行緒結束:" + new Date()); out.flush();
}
}
class AsyncExecutor implements Runnable {
private final AsyncContext ctx;
AsyncExecutor(AsyncContext ctx) { this.ctx = ctx; }
@Override public void run() {
try {
Thread.sleep(10000); // 模擬耗時業務
PrintWriter out = ctx.getResponse().getWriter();
out.println("業務完成:" + new Date()); out.flush();
ctx.complete(); // 結束非同步處理
} catch (Exception e) { e.printStackTrace(); }
}
}
req.startAsync():建立 AsyncContext,持有 Request/Response 參考。asyncSupported=true:在 @WebServlet 或 web.xml <async-supported>true</async-supported> 啟用。AsyncListener:監聽四大事件 onStartAsync/onError/onTimeout/onComplete,用於資源清理或日誌。web.xml 根元素 <web-app metadata-complete="true"> 可關閉掃描 (預設 false,即啟用註解掃描)。
| 屬性 | 對應 web.xml | 說明 |
|---|---|---|
| name | <servlet-name> | 預設為完整類別名 |
| urlPatterns / value | <url-pattern> | URL 映射,二選一 |
| loadOnStartup | <load-on-startup> | 啟動順序 |
| initParams | <init-param> | 初始化參數陣列 |
| asyncSupported | <async-supported> | 啟用非同步 |
@WebServlet(
urlPatterns={"/simple"},
asyncSupported=true,
loadOnStartup=-1,
name="SimpleServlet",
displayName="ss",
initParams={@WebInitParam(name="username", value="tom")}
)
public class SimpleServlet extends HttpServlet { ... }