Servlet的創(chuàng)建方式
1)實現(xiàn)Servlet接口
2)繼承GenericServlet
3)繼承HttpServlet
servlet何時被創(chuàng)建
1)默認情況下,用戶第一次訪問servlet實例的時候像棘,web容器將創(chuàng)建這個servlet實例
2)web.xml如果指定了load-on-startup嫉父,servlet容器在創(chuàng)建servlet時會按照優(yōu)先級加載servlet
<load-on-startup>num</load-on-startup>
- 當num值為0或者大于0時,表示容器在應(yīng)用啟動時就加載這個servlet福青。
- 當num值小于0或者沒有指定時摄狱,則指示容器在該servlet被選擇時才加載。
- 正數(shù)的值越小素跺,啟動該servlet的優(yōu)先級越高二蓝。
配置初始化參數(shù)
在Servlet的配置文件web.xml中,可以使用一個或多個<init-param>標簽為servlet配置一些初始化參數(shù)指厌。
其實相當于某個servlet的局部變量刊愚。將配置信息放在在web.xml中可以方便修改。
配置:
<servlet>
<servlet-name>basic</servlet-name>
<servlet-class>com.briup.prep.day01.BasicServlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>licy</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
獲炔妊椤:
String password = getServletConfig().getInitParameter("username");
ServletContext對象
ServletContext application
值的范圍是:一個應(yīng)用
WEB容器在啟動時鸥诽,它會為每個WEB應(yīng)用程序都創(chuàng)建一個對應(yīng)的ServletContext對象,它代表當前web應(yīng)用箕憾。
ServletConfig對象中維護了ServletContext對象的引用牡借,開發(fā)人員在編寫servlet時,可以通過config.getServletContext()方法獲得ServletContext對象袭异。
它相當于整個服務(wù)器的全局變量钠龙,也就是說只有關(guān)閉服務(wù)器的時候才找不到改數(shù)據(jù)
-
多個Servlet通過ServletContext對象實現(xiàn)數(shù)據(jù)共享
ServletContext context = this.getServletConfig().getServletContext();
//獲得ServletContext對象
context.setAttribute("data", data); //將data存儲到ServletContext對象中 -
獲取WEB應(yīng)用的初始化參數(shù)
<!-- 配置WEB應(yīng)用的初始化參數(shù) --> <context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/test</param-value> </context-param>
-
用servletContext實現(xiàn)請求轉(zhuǎn)發(fā)
context.getRequestDispatcher("/login.jsp").forward(request, response);
-
使用servletContext讀取資源文件db.properties中保存的是類似與driver=com.mysql.driver.Driver的配置信息
InputStream is = context.getResourceAsStream("/WEB-INF/init/db.properties"); Properties prop = new Properties(); prop.load(is); String name = (String) prop.getProperty("name"); String gender = prop.getProperty("gender");
HttpServletResponse
-
向客戶端(瀏覽器)發(fā)送數(shù)據(jù)的相關(guān)方法
getOutputStream() getWriter()
-
向客戶端(瀏覽器)發(fā)送響應(yīng)頭的相關(guān)方法
addDateHeader() addHeader() addIntHeader() containsHeader() setDateHeader() setHeader() setIntHeader() 例如: response.setHeader("content-type", "text/html;charset=UTF-8");
下載實例:
private void downloadFileByOutputStream(HttpServletResponse response)
throws FileNotFoundException, IOException {
//1.獲取要下載的文件的絕對路徑
String realPath = this.getServletContext().getRealPath("/download/1.JPG");
//2.獲取要下載的文件名
String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
//3.設(shè)置content-disposition響應(yīng)頭控制瀏覽器以下載的形式打開文件
response.setHeader("content-disposition", "attachment;filename="+fileName);
//4.獲取要下載的文件輸入流
InputStream in = new FileInputStream(realPath);
int len = 0;
//5.創(chuàng)建數(shù)據(jù)緩沖區(qū)
byte[] buffer = new byte[1024];
//6.通過response對象獲取OutputStream流
OutputStream out = response.getOutputStream();
//7.將FileInputStream流寫入到buffer緩沖區(qū)
while ((len = in.read(buffer)) > 0) {
//8.使用OutputStream將緩沖區(qū)的數(shù)據(jù)輸出到客戶端瀏覽器
out.write(buffer,0,len);
}
in.close();
}
HttpServletRequest
HttpServletRequest對象代表客戶端的請求,當客戶端通過HTTP協(xié)議訪問服務(wù)器時御铃,
HTTP請求頭中的所有信息都封裝在這個對象中碴里,通過這個對象提供的方法,
可以獲得客戶端請求的所有信息上真。
- 作為容器
setAttribute(String name,Object o) 將數(shù)據(jù)作為request對象的一個屬性存放到request對象中
getAttribute(String name) 獲取request對象的name屬性的屬性值
removeAttribute(String name)移除request對象的name屬性
getAttributeNames() 獲取request對象的所有屬性名
- 作為容器
- 獲得客戶機信息
getRequestURL() 返回客戶端發(fā)出請求時的完整URL咬腋。
getRequestURI() 返回請求行中的資源名部分。
getRemoteAddr() 返回發(fā)出請求的客戶機的IP地址睡互。
getRemoteHost() 返回發(fā)出請求的客戶機的完整主機名根竿。
getRemotePort() 返回客戶機所使用的網(wǎng)絡(luò)端口號陵像。
getLocalAddr() 返回WEB服務(wù)器的IP地址。
getLocalName() 返回WEB服務(wù)器的主機名寇壳。
getQueryString()返回請求行中的參數(shù)部分醒颖。
getPathInfo() 返回請求URL中的額外路徑信息。
額外路徑信息是請求URL中的位于Servlet的路徑之后和查詢參數(shù)之前的內(nèi)容九巡,它以“/”開頭图贸。
- 獲得客戶機請求頭
getHeader(string name)
getHeaders(String name)
getHeaderNames()
- 獲得客戶機請求參數(shù)(客戶端提交的數(shù)據(jù))
getParameter(String) 方法(常用)
getParameterValues(String name)方法(常用)
getParameterNames() 方法(不常用)
getParameterMap() 方法(編寫框架時常用)
- 獲得客戶機請求參數(shù)(客戶端提交的數(shù)據(jù))
- request接收表單提交中文參數(shù)亂碼問題解決
get方式提交表單:
對于以get方式傳輸?shù)臄?shù)據(jù),request即使設(shè)置了以指定的編碼接收數(shù)據(jù)也是無效的冕广,
默認的還是使用ISO8859-1這個字符編碼來接收數(shù)據(jù)疏日,客戶端以UTF-8的編碼傳輸數(shù)據(jù)到服務(wù)器端,而服務(wù)器端的request對象使用的是ISO8859-1這個字符編碼來接收數(shù)據(jù)撒汉,服務(wù)器和客戶端溝通的編碼不一致因此才會產(chǎn)生中文亂碼的沟优。
(1)get方式的解決方案:
在接收到數(shù)據(jù)后,先獲取request對象以ISO8859-1字符編碼接收到的原始數(shù)據(jù)的字節(jié)數(shù)組睬辐,然后通過字節(jié)數(shù)組以指定的編碼構(gòu)建字符串挠阁,解決亂碼問題。
- request接收表單提交中文參數(shù)亂碼問題解決
String name = request.getParameter("name");//接收數(shù)據(jù)
//獲取request對象以ISO8859-1字符編碼接收到的原始數(shù)據(jù)的字節(jié)數(shù)組溯饵,
name =new String(name.getBytes("ISO8859-1"), "UTF-8") ;
然后通過字節(jié)數(shù)組以指定的編碼構(gòu)建字符串侵俗,解決亂碼問題
(2) server.xml中配置
URIEncoding=utf-8
3)post方式提交表單:
之所以會產(chǎn)生亂碼,就是因為服務(wù)器和客戶端溝通的編碼不一致造成的丰刊,因此解決的辦法是:在客戶端和服務(wù)器之間設(shè)置一個統(tǒng)一的編碼隘谣,之后就按照此編碼進行數(shù)據(jù)的傳輸和接收。
request.setCharacterEncoding("UTF-8");
response.setHeader("content-type", "text/html;charset=utf-8");
- Request對象實現(xiàn)請求轉(zhuǎn)發(fā)
request.getRequestDispatcher("/test.jsp").forward(request, response);
request.getRequestDispatcher("/test.jsp").include(request, response);
調(diào)用forward()方法后啄巧,原先存放在HttpResponse對象中的內(nèi)容將會自動被清除
調(diào)用include()方法后寻歧,原先存放在HttpResponse對象中的內(nèi)容將不會被清除,內(nèi)容追加
1)內(nèi)部跳轉(zhuǎn)
請求次數(shù): 一次
瀏覽器地址欄地址: 不改變
實現(xiàn)方式: request.getRequestDispatch()
application.getRequestDispatch()
2)外部跳轉(zhuǎn)
請求次數(shù): 兩次
瀏覽器地址欄地址:改變
實現(xiàn)方式:response.sendRedirect();
Cookie & Session
1) Cookie
Cookie在服務(wù)器端產(chǎn)生的秩仆,以文件的形式保存在客戶端的码泛,
客戶端每次發(fā)送請求,都會將相應(yīng)的Cookie發(fā)送給服務(wù)器端
創(chuàng)建Cookie Cookie c = new Cookie()
保存Cookie response.addCookie(c) 傳遞到瀏覽器端澄耍,瀏覽器就會保存一個cookie噪珊,下次請求相同的路徑時就要攜帶cookie
得到所有的Cookie request.getCookies();
cookie的存活期:默認為-1,會話cookie
會話Cookie:把Cookie保存到瀏覽器上齐莲,當存活期為負數(shù)
持久Cookie:把Cookie保存到文件中卿城,當存活期為正數(shù)
設(shè)置存活期:c.setMaxAge();
2) session
值的范圍是:一次會話。
創(chuàng)建于服務(wù)器端铅搓,保存于服務(wù)器,維護于服務(wù)器端,每創(chuàng)建一個新的Session,服務(wù)器端都會分配一個唯一的ID搀捷,并且把這個ID保存到客戶端的Cookie中星掰,保存形式是以JSESSIONID來保存的多望。
- 創(chuàng)建session
1,HttpSession session=request.getSession();
2氢烘,request.getSession(true);第二種創(chuàng)建方式怀偷,默認為true,有session就調(diào)用那個session播玖,沒有就自動創(chuàng)建一個
保存數(shù)據(jù) setAttribute(string,object)
取數(shù)據(jù) getAttribute(key);
設(shè)置最大存活期
session.setMaxInactiveInterval(秒數(shù));
當瀏覽器被禁用椎工,session不能使用的時候,就采用重寫URL蜀踏,就是在URL地址后加上JSESSIONID
String url = response.encodeURL(path);
response.sendRedirect(url);
3)request
值的范圍是:一次請求维蒙。
路徑問題
1)在servlet當中 /-->相當于webcontent,項目的根目錄
2)在jsp 當中 /-->相當于webapps果覆,服務(wù)器的根目錄
過濾器
Filter 并不是一個標準的Servlet 颅痊,它不能處理用戶請求,也不能對客戶端生成響應(yīng)局待。主要用于對HttpServletRequest 進行預(yù)處理斑响,也可以對HttpServletResponse 進行后處理,是個典型的處理鏈钳榨。
過濾器類:
public class EncodingFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
}
public void init(FilterConfig config) throws ServletException { }
}
配置文件
<filter>
<filter-name>encodingFilter</filter-name>
<<filter-name>com.briup.filter.EncodingFilter</filter-name>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Filter的配置與在web.xml配置文件中的無關(guān)舰罚,F(xiàn)ilter的配置可以放在servlet的之上也可以之后。
但是多個Filter的filter-mapping配置的順序會影響到doFilter()方法的執(zhí)行順序薛耻。
將請求傳遞給下一個過濾器:
chain.doFilter(request, response);
監(jiān)聽器
Listener是Servlet的監(jiān)聽器营罢,它可以監(jiān)聽客戶端的請求、服務(wù)端的操作等昭卓。
通過監(jiān)聽器愤钾,可以自動激發(fā)一些操作,比如監(jiān)聽在線的用戶的數(shù)量候醒。
當增加一個HttpSession時能颁,就激發(fā)sessionCreated(HttpSessionEvent se)方法,
這樣就可以給在線人數(shù)加1倒淫。常用的監(jiān)聽接口有以下幾個:
ServletContextListener
ServletContextAttributeListener
SessionListener
SessionAttributeListener
SessionBindingListener
ServletRequestListener
ServletRequestAttributeListener
HttpSessionListener:監(jiān)聽session的創(chuàng)建和銷毀
想知道listener什么時候創(chuàng)建的伙菊,我們可以寫構(gòu)造函數(shù)來實現(xiàn)。
listener的配置
<listener>
<listener-class>com.huihui.day03.MySessionListener</listener-class>
</listener>