十.多個Servlet之間調用規則
1.前提條件:html
- 某些來自於瀏覽器發送請求,每每須要服務端中多個Servlet協同處理。
可是瀏覽器一次只能訪問一個Servlet,致使用戶須要手動經過瀏覽器 發起屢次請求才能獲得服務。
這樣增長用戶得到服務難度,致使用戶放棄訪問當前網站【98k,AKM】java
2.提升用戶使用感覺規則:web
不管本次請求涉及到多少個Servlet,用戶只須要【手動】通知瀏覽器發起 一次請求便可api
3.多個Servlet之間調用規則:瀏覽器
1)重定向解決方案 2)請求轉發解決方案服務器
1.重定向解決方案
1.工做原理: 用戶第一次經過【手動方式】通知瀏覽器訪問OneServletcookie
- OneServlet工做完畢後,將TwoServlet地址寫入到響應頭
location屬性中,致使Tomcat將302狀態碼寫入到狀態行 在瀏覽器接收到響應包以後,會讀取到302狀態。此時瀏覽器
自動根據響應頭中location屬性地址發起第二次請求,訪問 TwoServlet去完成請求中剩餘任務
2.實現命令:session
response.sendRedirect(「請求地址」)
將地址寫入到響應包中響應頭中location屬性app
3.特徵:ide
(1)請求地址:
- 既能夠把當前網站內部的資源文件地址發送給瀏覽器 (/網站名/資源文件名)
也能夠把其餘網站資源文件地址發送給瀏覽器(http://ip地址:端口號/網站名/資源文件名)
(2)請求次數
- 瀏覽器至少發送兩次請求,可是隻有第一次請求是用戶手動發送。 後續請求都是瀏覽器自動發送的。
(3) 請求方式
- 重定向解決方案中,經過地址欄通知瀏覽器發起下一次請求,所以 經過重定向解決方案調用的資源文件接收的請求方式必定是【GET】
4.缺點:
- 重定向解決方案須要在瀏覽器與服務器之間進行屢次往返,大量時間 消耗在往返次數上,增長用戶等待服務時間
2.請求轉發解決方案:
1.原理:
- 用戶第一次經過手動方式要求瀏覽器訪問OneServlet。
OneServlet工做完畢後,經過當前的請求對象代替瀏覽器 向Tomcat發送請求,申請調用TwoServlet。 Tomcat在接收到這個請求以後,自動調用TwoServlet來完成剩餘任務
2.實現命令: 請求對象代替瀏覽器向Tomcat發送請求
//1.經過當前請求對象生成資源文件申請報告對象
RequestDispatcher report =request.getRequestDispatcher("/資源文件名");必定要以"/"爲開頭
//2.將報告對象發送給Tomcat
report.forward(當前請求對象,當前響應對象)
3.優勢:
1)不管本次請求涉及到多少個Servlet,用戶只須要手動經過瀏覽器發送一次請求
2) Servlet之間調用發生在服務端計算機上,節省服務端與瀏覽器之間往返次數
增長處理服務速度
4.特徵:
(1)請求次數
- 在請求轉發過程當中,瀏覽器只發送一次請求
(2)請求地址
- -只能向Tomcat服務器申請調用當前網站下資源文件地址 request.getRequestDispathcer("/資源文件名") 不要寫網站名
(3)請求方式
- 在請求轉發過程當中,瀏覽器只發送一個了個Http請求協議包。 參與本次請求的全部Servlet共享同一個請求協議包,所以
這些Servlet接收的請求方式與瀏覽器發送的請求方式保持一致
十一.多個Servlet之間數據共享實現方案:
1.數據共享:OneServlet工做完畢後,將產生數據交給TwoServlet來使用
2.Servlet規範中提供四種數據共享方案
1. ServletContext接口(全局做用域對象)
1.介紹:
- 來自於Servlet規範中的一個接口。若有有兩個Servlet來自同一個網站。彼此之間經過ServletContext實現對象共享。
2.工做原理:
- 每個網站都存在一個全局做用域對象。這個全局做用域對象至關於一個Map.
3.全局做用域對象生命週期
- 在Http服務器啓動的過程當中,自動爲當前網站在內存中建立一個全局做用域對象.
注意:在Http服務器運行期間是,一個往回走哪隻有一個全局做用域對象,Http運行期間,全局做用域對象一直處於存活
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.經過請求對象向Tomcat索要當前網站全局做用域對象 ServletContext application = request.getServletContext(); //2.將數據添加到全局做用域對象,做爲共享數據 application.setAttribute("key1", 100); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.經過請求對象向Tomcat索要當前網站全局做用域對象 ServletContext application = request.getServletContext(); //2.從全局做用域對象獲得指定關鍵字對應的值 Integer money=(Integer)application.getAttribute("key1"); }
2. Cookie類(私人儲存卡)
1.介紹:
- cookie來自於Servlet規範中一個工具類,存在於Tomcat提供的servlet-api.jar中
- cookie存放當前用戶的私人數據,在共享數據過程當中提升服務質量
2.原理 - 用戶經過瀏覽器第一次向MyWeb網站發送請求申請OneServlet.
- OneServlet在運行期間建立一個Cookie存儲於當前用戶相關數據
- OneServlet工做完畢後,將Cookie寫入相應頭
3.實現命令
public class OneServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userName,money; //1.調用請求對象讀取【請求頭】參數信息 userName = request.getParameter("userName"); money = request.getParameter("money"); //2.開卡 Cookie card1 = new Cookie("userName", userName); Cookie card2 = new Cookie("money",money); //3.髮卡,將Cookie寫入到響應頭交給瀏覽器 response.addCookie(card1); response.addCookie(card2); //4.通知Tomcat將【點餐頁面】內容寫入到響應體交給瀏覽器(請求轉發) request.getRequestDispatcher("/index_2.html").forward(request, response); } } public class TwoServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int jiaozi_money = 30; int gaifan_money = 15; int miantiao_money = 20; int money = 0, xiaofei = 0, balance = 0; String food, userName = null; Cookie cookieArray[] = null; response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); Cookie newCard = null; //1.讀取請求頭參數信息,獲得用戶點餐食物類型 food = request.getParameter("food"); //2.讀取請求中Cookie cookieArray = request.getCookies(); //3.刷卡消費 for (Cookie card : cookieArray) { String key = card.getName(); String value = card.getValue(); if ("userName".equals(key)) { userName = value; } else if ("money".equals(key)) { money = Integer.valueOf(value); if ("餃子".equals(food)) { if (jiaozi_money > money) { out.print("用戶 " + userName + " 餘額不足,請充值"); } else { newCard = new Cookie("money", (money - jiaozi_money) + ""); xiaofei = jiaozi_money; balance = money - jiaozi_money; } } else if ("麪條".equals(food)) { if (miantiao_money > money) { out.print("用戶 " + userName + " 餘額不足,請充值"); } else { newCard = new Cookie("money", (money - miantiao_money) + ""); xiaofei = miantiao_money; balance = money - miantiao_money; } } else if ("蓋飯".equals(food)) { if (gaifan_money > money) { out.print("用戶 " + userName + " 餘額不足,請充值"); } else { newCard = new Cookie("money", (money - gaifan_money) + "");// 10+"abc"="10abc" xiaofei = gaifan_money; balance = money - gaifan_money; } } } } //4.將用戶會員卡返還給用戶 response.addCookie(newCard); //5.將消費記錄寫入到響應 out.print("用戶 " + userName + "本次消費 " + xiaofei + " 餘額 :" + balance); } }
4.Cookie銷燬時機
-
Cookie對象默認存放在瀏覽器上,所以瀏覽器關閉,Cookie對象就會被銷燬,
在手動設置狀況下,能夠要求瀏覽器將接受的Cookie存放在客戶端硬盤上。cookie.setMaxAge(60); //cookie在硬盤上存活1分鐘
3.HttpSession接口(會話做用域對象)
1.介紹:
- HttpSession接口來自於Servlet規範下一個接口
若是兩個Servlet來自於一樣一個網站,而且爲同一個瀏覽器、用戶提供服務,此時藉助於HTTPSession對象進行共享 - 開發人員習慣於將HttpSession接口修飾對象稱爲【會話做用域對象】
2.HttpSession於Cookie區別:
- 儲存位置不一樣:Cookie存放在客戶端的計算機(瀏覽器內存/硬盤)HttpSession存放在服務端計算機內存。
- 數據類型:Cookie對象存儲共享數據只能是String,HttpSession對象能夠存儲任意類型的共享數據Object。
- 數據數量:一個Cookie對象只能存儲一個共享數據,HttpSession使用map集合存儲共享數據,因此儲存任意數據。
- 參照物:Cookie至關於客戶在服務器的【會員卡】,HttpSession至關於客戶在服務端的【私人保險箱】。
3.命令實現:
//OneServlet代碼 public class OneServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String goodsName; //1.調用請求對象,讀取請求頭參數,獲得用戶選擇商品名 goodsName = request.getParameter("goodsName"); //2.調用請求對象,向Tomcat索要當前用戶在服務端的私人儲物櫃 HttpSession session = request.getSession(); //session.setMaxInactiveInterval(5); //3.將用戶選購商品添加到當前用戶私人儲物櫃 Integer goodsNum = (Integer)session.getAttribute(goodsName); if(goodsNum == null){ session.setAttribute(goodsName, 1); }else{ session.setAttribute(goodsName, goodsNum+1); } } } //TwoServlet代碼 public class TwoServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.調用請求對象,向Tomcat索要當前用戶在服務端私人儲物櫃 HttpSession session = request.getSession(); //2.將session中全部的key讀取出來,存放一個枚舉對象 Enumeration goodsNames =session.getAttributeNames(); while(goodsNames.hasMoreElements()){ String goodsName =(String) goodsNames.nextElement(); int goodsNum = (int)session.getAttribute(goodsName); System.out.println("商品名稱 "+goodsName+" 商品數量 "+goodsNum); } } }
4.Http服務器如何將用戶與HttpSession關聯起來
Cookie
5.getSession()與getSession(false)
(1)getSession(),若是當前用戶在服務端擁有本身的私人儲藏櫃,返回當前儲藏櫃,若是沒有建立新的私人儲藏櫃而且返回。
(2)getSeeion(false),若是當前客戶在服務端沒有私人儲存櫃,返回null。
6.HttpSession空閒時間手動設置
在當前網站/web/WEB-INF/web.xml
5
4.HttpServletRequest接口(請求做用域對象)
介紹:
- 在請求對象實現Servlet之間數據共享功能時,開發人員將請求對象稱爲【請求做用域對象】
實現命令:
OneServlet{ public void doGet(HttpServletRequest request,HttpServletResponse response){ //1.將數據添加到【請求做用域對象】中attribute屬性 request.setAttribute("key1",數據); //數據類型能夠任意類型Object //2.向Tomcat申請調用TwoServlet request.getRequestDispatcher("/two").forward(req,response) } } TwoServlet{ public void doGet(HttpServletRequest request,HttpServletResponse response){ //從當前請求對象獲得OneServlet寫入到共享數據 Object 數據 = request.getAttribute("key1"); } }
十二.監聽器接口
1.介紹:
- 監聽器接口用於監控【做用域對象生命週期變化】以及【做用域對象共享數據變化時刻】
2.做用域對象
- ServletContext:全局做用域對象。
- HttpSesssion:會話做用域對象
- HttpServletRequest:請求做用域對象
3.監聽器接口實現類開發規範:三步
1)根據監聽的實際狀況,選擇對應監聽器接口進行實現
2)重寫監聽器接口聲明【監聽事件處理方法】
3)在web.xml文件將監聽器接口實現類註冊到Http服務器
4.ServletContextListener接口:
1)做用:經過這個接口合法的檢測全局做用域對象被初始化時刻以及被銷燬時刻
2)監聽事件處理方法:
public void contextInitlized() 在全局做用域對象被Http服務器初始化被調用
public void contextDestory() 在全局做用域對象被Http服務器銷燬時候觸發調用
5.ServletContextAttributeListener接口:
- 監聽事件處理方法:
public void contextAdd():在全局做用域對象添加共享數據
public void contextReplaced():在全局做用域對象更新共享數據
public void contextRemove():在全局做用域對象刪除共享數據
6.全局做用域對象共享數據變化時刻
ServletContext application = request.getServletContext();
application.setAttribute(「key1」,100); //新增共享數據
application.setAttribute(「key1」,200); //更新共享數據
application.removeAttribute(「key1」); //刪除共享數據
十三.Filter接口(過濾器接口)
1.介紹:
- Filter接口實現類由開發人員負責提供,Http服務切不負責提供
- Filter接口在Http服務器調用資源文件以前,對Http服務器進行攔截
2.具體做用:
1)攔截Http服務器,幫助Http服務器檢測當前請求合法性
2)攔截Http服務器,對當前請求進行加強操做
3.Filter接口實現類開發步驟:三步
1)建立一個Java類實現Filter接口
2)重寫Filter接口中doFilter方法
3)web.xml將過濾器接口實現類註冊到Http服務器
4.Filter攔截地址格式
(1) 命令格式:
<filter-mapping> <filter-name>oneFilter</filter-name> <url-pattern>攔截地址</url-pattern> </filter-mapping>
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("攔截請求......"); chain.doFilter(request, response);//放行 System.out.println("攔截響應......"); }
(2) 命令做用:
攔截地址通知Tomcat在調用何種資源文件以前須要調用OneFilter過濾進行攔截
(3)要求Tomcat在調用某一個具體文件以前,來調用OneFilter攔截
<url-pattern>/img/mm.jpg</url-pattern>
(4)要求Tomcat在調用某一個文件夾下全部的資源文件以前,來調用OneFilter攔截
<url-pattern>/img/*</url-pattern>
(5)要求Tomcat在調用任意文件夾下某種類型文件以前,來調用OneFilter攔截
<url-pattern>*.jpg</url-pattern>
(6)要求Tomcat在調用網站中任意文件時,來調用OneFilter攔截
<url-pattern>/*</url-pattern>