市面上有 500+ Web 框架,本質皆為 Servlet API 的二次封裝。框架隱藏了 HTTP 協議細節,讓開發者專注業務,但若跳過 Servlet 規範直接學框架:
HttpServletRequest/Response、Filter、Session 等核心契約理解膚淺。bin/startup.sh,日誌直觀可控。webapp/WEB-INF/web.xml、webapp/WEB-INF/lib/servlet-api.jar(僅編譯用,運行期由容器提供)。<Context path="" docBase="D:/WORKDIR/ServletDemo/webapp" reloadable="true"/>
將專案 webapp 目錄掛載為根上下文,修改類/JSP 即時生效(reloadable=true)。
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>demo.HelloServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
public class HelloFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletRequest request = (HttpServletRequest) req;
System.out.println("攔截 URI: " + request.getRequestURI());
chain.doFilter(req, res); // 傳遞給下一個過濾器或 Servlet
}
}
配置順序:<filter-mapping> 必須置於 <servlet-mapping> 之前,否則 Filter 不生效。
| HTTP 概念 | Servlet API | 核心方法 |
|---|---|---|
| Request Line / Header / Body | HttpServletRequest | getRequestURI(), getHeader(), getInputStream(), getParameter() |
| Response Status / Header / Body | HttpServletResponse | setStatus(), setHeader(), getOutputStream(), getWriter() |
| Session 會話 | HttpSession | getAttribute(), setAttribute(), getId() |
| 上下文共享 | ServletContext | getAttribute(), getResourceAsStream() |
必背介面:HttpServletRequest、HttpServletResponse、HttpSession、ServletContext、FilterChain、RequestDispatcher、各類 Listener。
Map<String, HttpSession>,Key 為 JSESSIONID。request.getSession():獲取或建立 Session,自動發送 Set-Cookie: JSESSIONID=xxx; Path=/; HttpOnly。MaxAge=-1 表示瀏覽器進程級生命週期,關閉瀏覽器即銷毀。JSP 首次訪問由 Jasper 編譯為 HttpJspBase 子類(本質是 Servlet),產物位於 tomcat/work/Catalina/localhost/專案/org/apache/jsp/。JSP 適合視圖渲染,Servlet 適合控制邏輯,現代開發建議使用模板引擎(Velocity、Thymeleaf)替代 JSP。
框架是工具,應聽命於你,而非綁架你的思維。掌握 Servlet 核心,看任何框架源碼皆「小菜一碟」。
