Servlet 知識(shí)點(diǎn)匯總
@WebServlet 注解
注解配置樣例 @WebServlet(name=“HelloServlet”,urlPatterns={"/hello"})
| 屬性名 | 類型 | 屬性描述 |
|---|---|---|
| name | String | Servlet的名稱。等價(jià)于<Servlet-name>。如沒有顯式指定,則該取值為類的全限定名. |
| value | String[] | 等價(jià)于urlPatterns,二者不能共存。 |
| urlPatterns | String[] | 指定一組servlet的url的匹配模式,等價(jià)于<url-pattern>標(biāo)簽。 |
| loadOnStartup | int | 指定servlet的加載順序,數(shù)字大于0則表示啟動(dòng)時(shí)初始化,數(shù)字越小初始化越早,等價(jià)于<load-on-startup>標(biāo)簽。 |
| initParams | WebInitParam[] | 指定一組初始化參數(shù),等價(jià)于<init-param>標(biāo)簽。 |
| asyncSupported | boolean | 聲明servlet是否支持異步操作模式,等價(jià)于<async-supported>標(biāo)簽。 |
| displayName | String | servlet的顯示名,等價(jià)于<display-name>標(biāo)簽。 |
| description | String | servlet的描述信息,等價(jià)于<description>標(biāo)簽。 |
@MultipartConfig 注解
注解配置樣例 @MultipartConfig(location="c:/workspace")
| 屬性名 | 類型 | 屬性描述 |
|---|---|---|
| fileSizeThreshold | int | 若上傳文件大小超過設(shè)置門檻,則會(huì)先寫入緩存文件,默認(rèn)值為 0 |
| location | String | 設(shè)置寫入文件時(shí)的目錄,可搭配 Part 的 write() 方法用,默認(rèn)為空字符 |
| maxFileSize | long | 限制上傳文件大小,默認(rèn)值為 -1L,表示不限大小。 |
| maxRequestSize | long | 限制 multipart/form-data 請(qǐng)求個(gè)數(shù),默認(rèn)值為 -1L,表示不限個(gè)數(shù)。 |
使用 web.xml
文件位于 WEB-INF 文件夾內(nèi)。web.xml 中的設(shè)置會(huì)覆蓋 Servlet 中的標(biāo)注設(shè)置。
- 定義 Servlet 的屬性
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>cc.openhome.HelloServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<servlet>
- 定義 Servlet 的映射
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloUser.view</url-pattern>
</servlet-mapping>
- 定義歡迎頁(yè)面
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
- 定義 @MultipartConfig 對(duì)應(yīng)的信息,將 <multipart-config> 加到對(duì)應(yīng)的 <servlet> 標(biāo)簽中
<multipart-config>
<location>c:/workspace</location>
</multipart-config>
- 定義默認(rèn)的區(qū)域與編碼的對(duì)應(yīng)關(guān)系(例如默認(rèn)將中國(guó)大陸對(duì)應(yīng)使用 UTF-8 )
<locale-encoding-mapping-list>
<locale-encoding-mapping>
<locale>zh_CN</locale>
<encoding>UTF-8</encoding>
</local-encoding-mapping>
<locale-encoding-mapping-list>
- 設(shè)置文件后綴名與 MIME 類型的對(duì)應(yīng)關(guān)系 (可以通過 servletContext 的 getMimeType() 方法獲得)
<mime-mapping>
<extension>pdf</extension>
<mime-type>application/pdf</mime-type>
</mime-mapping>
- 設(shè)置 HttpSession 的失效時(shí)間 (單位為秒)
<session-config>
<session-timeout>30</session-timeout>
</session-config>
- 在 web.xml 中設(shè)定 SessionCookieConfig 信息
<session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<name>sid-caterpillar</name>
<http-only>true</http-only>
</cookie-config>
</session-config>
URL 模式設(shè)置
一個(gè)請(qǐng)求 URI 實(shí)際上由三個(gè)部分組成:
requestURI = contextPath + servletPath + pathInfo
URL 模式 (如果模式匹配重復(fù),則默認(rèn)按照最嚴(yán)格的模式優(yōu)先):
- 路徑映射 如 "/guest/*
- 擴(kuò)展映射 如 "*.view"
- 環(huán)境根目錄映射 如 "/"
- 預(yù)設(shè) Servlet 當(dāng)找不到合適的 URL 模式對(duì)應(yīng)時(shí),就會(huì)使用預(yù)設(shè) Servlet。
- 完全匹配 如 "/guest/test.view"
請(qǐng)求對(duì)象編碼詳解
- Web 容器默認(rèn)編碼處理是 ISO-8859-1
- POST 方式的請(qǐng)求,可以使用 request.setCharacterEncoding() 方法指定編碼
- GET 方式的請(qǐng)求,可以以下方式來指定編碼 ( 因?yàn)?setCharacterEncoding 只對(duì) body 有效,對(duì) URI 無效 )
String name = request.getParameter("name");
String name = new String(name.getBytes("ISO-8859-1"),"UTF-8");
- 和前端協(xié)商好編碼的類型,以此確定服務(wù)器端的解碼類型。
HttpServletRequest
代表 Http 請(qǐng)求報(bào)文的類
| 方法 | 方法簽名 | 方法功能 |
|---|---|---|
| getParameter | java.lang.String getParameter(java.lang.String name) | 返回請(qǐng)求參數(shù),如果不存在則返回 null |
| getRequestURI | java.lang.String getRequestURI() | 獲取請(qǐng)求 URI |
| getContextPath | java.lang.String getContextPath() | 獲取環(huán)境路徑 contextPath |
| getServletPath | java.lang.String getServletPath() | 獲取 Servlet 路徑 |
| getPathInfo | java.lang.String getPathInfo() | 獲取路徑信息 |
| getParameterValues | java.lang.String[] getParameterValues(java.lang.String name) | 獲取同一請(qǐng)求名稱的多個(gè)值 |
| getParameterMap | java.util.Map<java.lang.String,java.lang.String[]> getParameterMap() | 將請(qǐng)求參數(shù)以 Map 形式返回 |
| getHeader | java.lang.String getHeader(java.lang.String name) | 返回 Http 請(qǐng)求首部 |
| getHeaders | java.util.Enumeration<java.lang.String> getHeaders(java.lang.String name) | 返回同一首部參數(shù)的多個(gè)值 |
| getHeaderNames | java.util.Enumeration<java.lang.String> getHeaderNames() | 返回所有 Http 首部參數(shù)名 |
| getDateHeader | long getDateHeader(java.lang.String name) | 將 Http 首部特定參數(shù)的值轉(zhuǎn)換為 Date 的值 |
| getIntHeader | int getIntHeader(java.lang.String name) | 將 Http 首部特定參數(shù)的值轉(zhuǎn)換為 int |
| getReader | java.io.BufferedReader getReader() | 取得 BufferedReader 來讀取請(qǐng)求的 Body 數(shù)據(jù) |
| getInputStream | ServletInputStream getInputStream() | 返回請(qǐng)求報(bào)文主體的二進(jìn)制字節(jié)數(shù)據(jù) |
| getRequestDispatcher | RequestDispatcher getRequestDispatcher(java.lang.String path) | 獲得請(qǐng)求分配器,可以轉(zhuǎn)發(fā)或包含相對(duì)的 URL 地址 |
| getLocale | java.util.Locale getLocale() | 獲取地區(qū)信息 |
- 若使用 Servlet 處理上傳的文件,可以使用 Java IO 結(jié)合 getInputStream()。判斷上傳的文件的開始位置和結(jié)束位置,然后用字節(jié)流寫為文件。
- 若使用 Servlet 處理上傳的文件,也可以使用 getPart()、getParts() 方法。
- 使用 RequestDispatcher.include() 可以把其它 servlet 的操作流程包含到當(dāng)前的 servlet 操作流程之中。
HttpServletResponse
代表 Http 響應(yīng)報(bào)文的類
| 方法 | 方法簽名 | 方法功能 |
|---|---|---|
| getWriter | java.io.PrintWriter getWriter() | 取得響應(yīng)輸出對(duì)象 |
| setContentType | void setContentType(java.land.String type) | 設(shè)置響應(yīng)內(nèi)容類型 |
| setHeader | void setHeader(java.lang.String name, java.lang.String value) | 設(shè)置特定響應(yīng)標(biāo)頭的值 |
| addHeader | void addHeader(java.lang.String name, java.lang.String value) | 添加響應(yīng)標(biāo)頭的名稱和值 |
| setIntHeader | void setIntHeader(java.lang.String name, int value) | 如果對(duì)應(yīng)標(biāo)頭的值是整數(shù),可用此方法設(shè)置 |
| setDateHeader | void setDateHeader(java.lang.String name, long date) | 如果對(duì)應(yīng)標(biāo)頭的值是日期,可用此方法設(shè)置 |
| addIntHeader | void addIntHeader(java.lang.String name, int value) | 如果對(duì)應(yīng)標(biāo)頭的值是整數(shù),可用此方法添加 |
| addDateHeader | void addDateHeader(java.lang.String name, long date) | 如果對(duì)應(yīng)標(biāo)頭的值是日期,可用此方法添加 |
| setLocale | void setLocale(java.util.Locale loc) | 設(shè)置地區(qū)以及編碼行為 |
| setCharacterEncoding | void setCharacterEncoding(java.lang.String charset) | 設(shè)置字符編碼 |
| setContentType | void setContentType(java.lang.String type) | 設(shè)置內(nèi)容類型 |
| getOutputStream | ServletOutputStream getOutputStream() | 取得輸出的流對(duì)象 |
| sendRedirect | void sendRedirect(java.lang.String location) | 在響應(yīng)中設(shè)置狀態(tài)碼 301 以及 Location 標(biāo)頭,瀏覽器會(huì)根據(jù)新的 URL 進(jìn)行重定向 |
| sendError | void sendError(int sc) | 向?yàn)g覽器返回錯(cuò)誤狀態(tài)碼 |
| sendError | void sendError(int sc, java.lang.String msg) | 向?yàn)g覽器返回錯(cuò)誤狀態(tài)碼和相關(guān)錯(cuò)誤信息 |
- 容器可以對(duì)響應(yīng)進(jìn)行緩沖,可以操作 HttpServletResponse 以下有關(guān)緩沖的幾個(gè)方法
- getBufferSize() 獲取緩沖區(qū)大小
- setBufferSize() 設(shè)置緩沖區(qū)大小,必須在調(diào)用 getWriter 之前調(diào)用
- isCommitted() 查看響應(yīng)是否已經(jīng)確認(rèn)
- reset() 重置所有響應(yīng)信息,包括標(biāo)頭信息
- resetBuffer() 重置相應(yīng)信息,不包括標(biāo)頭信息
- flushBuffer() 清除所有緩沖區(qū)已設(shè)置的信息到客戶端
- 容器響應(yīng)關(guān)閉的時(shí)機(jī)點(diǎn) (容器關(guān)閉會(huì)清楚所有的響應(yīng)內(nèi)容):
- Servlet 的 service() 方法已結(jié)束,響應(yīng)的內(nèi)容長(zhǎng)度超過 HttpServletResponse 的 setContentLength() 所設(shè)置的長(zhǎng)度
- 調(diào)用了 sendRedirect() 方法
- 調(diào)用了 sendError() 方法
- 調(diào)用了 AsyncContext 的 complete() 方法
- 使用 ServletContext 對(duì)象獲取當(dāng)前 Web 應(yīng)用程序目錄內(nèi)的文件
- 使用 HttpServlet 的 getServletContext() 獲取 ServletContext 對(duì)象
- 使用 ServletContext 的 getResourceAsStream() 方法以串流讀取文件
- 使用 HttpServletResponse 的 getOutputStream() 獲取 ServletOutputStream 對(duì)象并進(jìn)行響應(yīng)輸出
會(huì)話管理
- 使用隱藏域:在 html 表單中使用 type='hidden' 來將數(shù)據(jù)寫入隱藏域
<form action='XXX' method='post'>
隱藏域 <input type='text' name='first' /><br />
<input type='hidden' name='second' value='1' />
<input type='hidden' name='third' value='2' />
<input type='submit' name='page' value='完成' />
</form>
使用這種方法,可以用 request.getParameters() 等方法獲取之前頁(yè)面中的數(shù)據(jù)
- 使用 Cookie
// 新建 Cookie 對(duì)象
Cookie cookie = new Cookie("name", "data");
// 設(shè)置 Cookie 有效期 (單位為秒)
cookie.setMaxAge(7 * 24 * 60 * 60);
// 將 cookie 添加到響應(yīng)中
response.addCookie(cookie);
Cookie 可以使用 request.getCookies() 來取得
- 使用 URL 重寫,即在超鏈接中包含相關(guān)信息,以 url 方式傳給 servlet
<a href='search?start=1' />
使用 HttpSession
在 Servlet/JSP 中,如果想進(jìn)行會(huì)話管理,可以使用 HttpServletRequest 的 getSession() 方法取得 HttpSession 對(duì)象
HttpSession session = request.getSession();
HttpSession 常用方法及其用途:
- setAttribute() 設(shè)置屬性
- getAttribute() 取得屬性
- invalidate() 注銷
- setMaxInactiveInternal() 設(shè)置瀏覽器多久沒有請(qǐng)求應(yīng)用程序,session 會(huì)失效 (單位為秒)
可以使用 ServletContext 的 getSessionCookieConfig() 來取得 SessionCookieConfig 接口的實(shí)現(xiàn)
HttpSession 與 URL 重寫
因?yàn)?HttpSession 的原理是使用 Cookie 存儲(chǔ) Session ID,所以如果用戶關(guān)掉瀏覽器接收 Cookie 的功能,就無法使用 Cookie 在瀏覽器存儲(chǔ) Session ID。如果在用戶禁用 Cookie 的情況下,仍然打算使用 HttpSession 來進(jìn)行會(huì)話管理,那么可以搭配 URL 重寫。
如果要使用 URL 重寫的方式來發(fā)送 Session ID,可以使用 HttpServletResponse 的 encodeURL() 協(xié)助產(chǎn)生所需的 URL 重寫。當(dāng)容器嘗試取得 HttpSession 實(shí)例時(shí),如果能從 Http 請(qǐng)求中獲得帶有 Session ID 的 Cookie ,那么 encodeURL() 將不對(duì) URL 做修改。而如果容器無法取得 Session ID 時(shí) (一般意味著用戶禁用了 cookie ),encodeURL() 將會(huì)自動(dòng)產(chǎn)生帶有 Session ID 的 URL 重寫。
encodeRedirectURL() 可以在瀏覽器重定向時(shí),在 URL 上顯示 Session ID
Servlet 進(jìn)階 API
Servlet
- init() 啟動(dòng)時(shí)
- service() 傳入請(qǐng)求和響應(yīng)對(duì)象
- destroy() 銷毀時(shí)
ServletConfig
使用 getServletConfig() 獲取 ServletConfig 對(duì)象
- getInitParameter(String name) 獲取對(duì)應(yīng)的 Servlet 設(shè)置參數(shù)
- getInitParameters() 獲取全體的 Servlet 設(shè)置參數(shù)
可以使用 @WebServlet 中的 initParam 屬性設(shè)置
initParams={
@WebInitParam{name="PARAM1",value="VALUE1"),
@WebInitParam{name="PARAM2",value="VALUE2")
}
ServletContext
使用 getServletContext() 獲取 ServletContext 對(duì)象
ServletContext 接口定義了運(yùn)行 Servlet 應(yīng)用程序環(huán)境的一些行為與觀點(diǎn),可以使用 ServletContext 實(shí)現(xiàn)對(duì)象來取得請(qǐng)求資源的 URL、設(shè)置與存儲(chǔ)屬性、應(yīng)用程序初始參數(shù)以及動(dòng)態(tài)設(shè)置 Servlet 實(shí)例等。
- getRequestDispatcher() 獲得請(qǐng)求分發(fā)器
- getResourcePaths() 獲得 Web 應(yīng)用程序某個(gè)目錄中有哪些文件
- getResourceAsStream() 獲得 Web 應(yīng)用程序某個(gè)文件的內(nèi)容,返回 InputStream
-
ServletContextListener
- 可以實(shí)現(xiàn)這個(gè)接口,來在應(yīng)用程序初始化或銷毀時(shí)進(jìn)行自定義操作
- 可以準(zhǔn)備好數(shù)據(jù)庫(kù)連接,讀取應(yīng)用程序設(shè)置等
- 使用 @WebListener 標(biāo)注
- contextInitialized()
- contextDestroyed()
-
ServletContextAttributeListener
- attributeAdded()
- attributeRemoved()
- attributeReplaced()
-
HttpSession 事件、監(jiān)聽器
- HttpSessionListener
- SessionCreated()
- SessionDestroyed()
- HttpSessionAttributeListener
- attributeAdded()
- attributeRemoved()
- attributeReplaced()
- HttpSessionBindingListener
- valueBound()
- valueUnbound()
- HttpSessionActivationListner
- sessionWillPassivate()
- sessionDidActivate()
- HttpSessionListener
-
HttpServletRequest 事件、監(jiān)聽器
- ServletRequestListener
- requestDestroyed()
- requestInitialized()
- ServletRequestAttributeListener()
- attributeAdded()
- attributeRemoved()
- attributeReplaced()
- ServletRequestListener
-
過濾器
- 可以通過實(shí)現(xiàn) Filter 接口,并使用 @WebFilter 標(biāo)注或在 web.xml 中定義過濾器。
- Filter 接口有三個(gè)要實(shí)現(xiàn)的方法:
- public void init(FilterConfig filterConfig)
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- public void destroy()
- chain.doFilter(request, response); 前執(zhí)行的代碼為 service() 前執(zhí)行的代碼,后執(zhí)行的代碼為 service() 后執(zhí)行的代碼
- @WebFilter(filterName="XXX", urlPatterns={"XXX"})
<filter> <filter-name>performance</filter-name> <filter-class>cc.openhome.PerformanceFilter</filter-class> </filter> <filter-mapping> <filter-name>performance</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>- 可以繼承 HttpServletRequestWrapper 來對(duì) HttpServletRequest 類進(jìn)行處理,然后再再 doFilter 中傳入 service()
- 可以繼承 HttpServletResponseWrapper 來對(duì) HttpServletResponse 類進(jìn)行處理。一般會(huì)在壓縮輸出中用到。
-
異步處理 AsyncContext
- 要使用 @WebServlet 注解告訴容器此 Servlet 支持異步處理 asyncSupported=true
劉豐璨 寫于 2018.04.15 9:00 Github: https://github.com/EdwardLiu-Aurora
更新于 2018.04.16 20:30