Servlet---JavaWeb技術的核心基礎,JavaWeb框架的基石(二)



一、Servlet之Request
        Web服務器會對收到的每一次客戶端http請求分別創建一個用於代表請求的request對象和代表響應的response對象。要獲取客戶端提交的數據需通過request,要想容器輸出數據需通過response。
        1、HttpServletRequest
           HttpServletRequest對象代表客戶端的請求,當客戶端通過HTTP協議訪問服務器時,HTTP請求頭中的所有信息都封裝在這個對象中,開發人員通過這個對象的方法可以會的客戶的相關信息。
        2、Request常用方法(參考官方API)
            獲得客戶機信息:
                 getRequestURL,返回客戶端發出請求時的完整URL
                 getRequestURI, 返回請求行中的資源名部分
                 getQueryString, 返回請求行中的查詢字符串,通常為?后邊攜帶的參數信息
                 getRemoteAddr, 返回客戶端IP地址
                 getRemoteHost, 返回客戶端的主機名
                 getRemotePort, 返回客戶端的網絡端口號
                 getLocalAddr, 返回Web服務器的IP地址
                 getLocalName, 返回Web服務器的主機名
                 getMethod, 返回客戶端的請求方式(get/post)
             獲得客戶機請求頭:
                 getHeader() 
                 getHeaders()
                 getHeaderNames()
             獲得客戶機請求參數:
                 getParameter()
                 getParameterValues()
                 getParameterNames
        3、Request請求參數的中文亂碼問題
              一般瀏覽器使用什么編碼,則傳送的數據就以什么編碼,但有許多Web瀏覽器不發送帶有“content-type”頭信息的字符編碼限定符,而由讀取http請求的代碼類決定自讀的編碼方式。
              默認情況下,如果客戶端請求未定義編碼限定符,容器(如Tomcat)會用“ISO-8859-1”去創建request reader 和解析post數據。
              注意:自從Tomcat5.x開始,GET和POST方法提交的信息,Tomcat采用了不同的方式來處理編碼,對於POST請求,Tomcat會仍然使用request.setCharacterEncoding方法所設置的編碼來處理,如果未設置,則使用默認的"ISO-8859-1"編碼。而對GET請求,並不會考慮使用request.setCharacterEncoding方法設置編碼,而會永遠使用“ISO-8859-1”編碼。        
              所以,一般的解決方式為:
                    POST方式:在最開始設置request.setCharacterEncoding("UTF-8")
                    GET方式: new String(username.getBytes("ISO-8859-1"),"UTF-8")
                    修改Tomcat的配置可以解決URL中中文編碼問題:<Connector URIEncoding="UTF-8"/>
          4、轉發和包含
                 一個Servlet對象無法獲得另一個Servlet對象的引用,如果需要多個Servlet組件共同協作(數據傳遞),只能使用Servlet規范提供的請求轉發和包含這兩種方式:
                  請求轉發:Servlet(源組件)先對客戶請求最初一些預處理操作,然后把請求轉發給其他web組件(目標組件)來完成包括生成響應結果在內的后續操作。
                  包含: Servlet(源組件)把其他web組件(目標組件)生成的響應結果包含到自身的響應結果中。
                  兩者共同點:
                         源組件和目標組件處理的都是同一個酷虎請求,源組件和目標組件共享同一個ServletRequest和ServletResponse對象。
                         目標組件可以為Servlet、JSP、HTML文檔等
                         都依賴javax.servlet.RequestDispatcher接口。
           5、RequestDispatcher請求分發器
                     它包含兩個方法:
                       forward():把請求轉發給目標組件
                       include():包含目標組件的響應結果
                     得到RequestDispatcher對象
                         1、ServletContext對象的getRequestDispatcher(String path1)。path1必須用絕對路徑,即以‘/’開頭,若用相對路徑會拋出IllegalArgumentException異常
                         2、ServletRequest對象的getRequestDispatcher(String path2)。 path2可以用絕對路徑也可以用相對路徑。
                     如果使用forward()方法,只會返回目標組件的響應結果,所以不應該在源組件中提交響應結果,而且,如果在源組件調用了Response的flush或close方法,會拋出IllegalStateException異常
                     如果使用include()方法,則源組件與目標組件的輸出都會被添加到響應結果中,在目標組件對響應頭做的修改會被忽略
           6、請求范圍
                     web應用范圍內的共享數據作為ServletContext對象的屬性而存在,只要共享ServletContext對象也就共享了其屬性。
                     請求范圍內的共享數據作為ServletRequest對象的屬性而存在,只要共享了ServletRequest對象,也就共享了其數據。
 
二、Servlet之Response
          1、HttpServletResponse
             HttpServletResponse對象代表服務器的響應,這個對象中封裝了向客戶端發送數據、發送響應頭,發送響應狀態碼的方法。
          2、Response常用方法
             setStatus();設置狀態碼
             setHeader();設置響應頭
             getWriter();返回一個響應的打印流
             getOutputStream();返回一個響應的字節輸出流
             注意:getWriter與getOutputStream兩個方法相互排斥,調用了其中一個方法后就不能再調用另一個,否側會拋出異常,Servlet引擎會檢查輸出流是否關閉,並調用close方法,所以不需要自己關閉。
          3、Response中的中文問題
             通過設置響應頭告知客戶端編碼方式:response.setHeader("Content-Type","text/html;charset=UTF-8")
             通過meta標簽模擬請求頭::out.write("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />".getBytes())
             通過直接方法:response.setContentType("text/html;charset=UTF-8");這條語句的作用是將自己的編碼設置為UTF-8,並告訴瀏覽器使用UTF-8解碼
          4、Response常見應用
              控制瀏覽器定時刷新:response.setHeader("Refresh","2");也可以定時刷新到某一個URL
              控制瀏覽器緩存當前文檔:
response.addDateHeader("Expires",System.currentTimeMillis()+1000*60*60);//緩存一小時,對於一些不怎么變化的數據,利用緩存能減輕服務器的負擔
              請求重定向:response.sendRedirect(location);
              重定向特點:
                 Servlet源組件生成的響應結果不會被發送到客戶端,response.sendRedirect(location)方法一律返回狀態碼為302的響應結果。
                 如果源組件在進行重定向之前,已經提交了響應結果,會拋出IllegalStateException異常,所以,不應該在元組件中提交響應結果。
                 Servlet源組件重定向語句后面的代碼也會執行。
                 源組件和目標組件不共享一個ServletRequest對象。
                 對於response.sendRedirect(location)方法的參數,如果以"/"開頭,表示相當於當前服務器根路徑的URL。以"http://"開頭,表示一個完整路徑。
                 目標組件不必是同一個服務器上的同一個web應用的組件,它可以是任意一個有效的網頁。
 
三、Cookie&Session
        1、什么是會話:     
            用戶開一個瀏覽器,點擊對個超鏈接,訪問服務器多個Web資源,然后關閉瀏覽器,整個過程稱之為一個會話。
            每個用戶在使用瀏覽器與服務器進行會話的過程中,不可避免各自會產生一些數據,程序要想辦法為每個用戶保存這些數據。
        2、保存會話數據的兩種技術:
              Cookie:Cookie是客戶端技術,程序把每個用戶的數據以cookie的形式寫給用戶各自的瀏覽器。當用戶使用瀏覽器再去訪問服務器中的Web資源時,就會帶着各自的數據去。這樣,web資源處理的就是用戶各自的數據了。
              HttpSession:Session是服務器端技術,利用這個技術,服務器在運行時可以為每一個用戶的瀏覽器 創建一個其獨享的HttpSession對象,由於session為用戶瀏覽器獨享,所以用戶在訪問服務器的web資源時,可以把各自的數據放在各自的session中,當用戶再去訪問服務器中的其他web資源是,其他web資源在從用戶各自的session中取出數據為用戶服務。
        3、Cookie API
            javax.servlet.http.Cookie類用於創建一個Cookie,response接口中定義了一個addCookie方法,它用於在其響應頭中增加一個相應的Set-Cookie頭字段。同樣,request接口中也定義了一個個頭Cookie方法,它用於獲取客戶端提交的Cookie。Cookie類的方法:
          public Cookie(String name,String value);
          setValue與getValue方法
          setMaxAge與getMaxAge方法
          setPath與getPath方法
          setDomain與getDomain方法
          getName方法
          由於Cookie保存在客戶端,所有,給不給傳Cookie是由瀏覽器決定的,取決於MYURL.startWith(domain+path)完全匹配。domain是主機名加端口號,path是從第一個"/"開始的文件路徑。
          cookie.setPath("/");可以讓該cookie在同一個服務器下的多個項目共享。
        4、Cookie細節
            一個Cookie只能表示一種信息,它至少患有一個標識該信息的名稱(name)和設置值(value)。
            一個Web應用可以給一個瀏覽器發送多個Cookie;一個瀏覽器也可以存儲多個Web網站的Cookie。
            每個瀏覽器有自己默認的存放Cookie個數,並限制每個站點存放Cookie的個數,每個Cookie的大小限制為4kb。
            如果創建了一個cookie,並將它發送到瀏覽器,默認情況下它是一個會話級別的cookie(即存儲在瀏覽器的內存中),用戶退出瀏覽器之后即被刪除,若希望瀏覽器將該cookie存儲在磁盤上,則需要使用maxAge,並給出一個以秒為單位的時間。將最大時效設為0則是命令瀏覽器刪除該cookie。
            注意,刪除cookie是,path必須一致,否則不會刪除。   
        5、Session       
            在web開發中,服務器可以為每個用戶瀏覽器創建一個會話對象(Session對象),把用戶數據寫到用戶瀏覽器獨占的Session中,當前用戶使一個瀏覽器獨占一個Session對象。因此,需要保存用戶數據時,服務器程序可以用Session保存,統一瀏覽器可以從用戶的Session中取出該用戶的數據,為用戶服務。
            Session對象有服務器創建,開發人員可以調用request對象的getSession方法得到Session對象。
            瀏覽器第一次請求時,服務器會在響應頭中加入Set-Cookie: JSESSIONID=022841F4A201530430481C66F0D29FB8; Path=/Day28ServletResponse/; HttpOnly。當瀏覽器下次請求時會攜帶這個Session的唯一標識,Cookie: JSESSIONID=022841F4A201530430481C66F0D29FB8。服務器就之后是同一個用戶的行為了。
            服務器內存中的每個Session都有一個32位的id作為唯一標識,Tomcat為每個Session默認的生存時間為30分中。
         6、瀏覽器禁用Cookie之后的Session處理
             瀏覽器禁用Cookie之后,就無法再請求中攜帶JSESSIONID內容,所以導致服務器共享出問題。Java提供URL重寫方案:
             response.encodeRedirectURL(url);對sendRedirect方法的URL地址進行重寫。
             response.encodeURL(url);對表單action和超鏈接的url地址進行重寫。
             如果用戶瀏覽器沒有禁用Cookie,重寫方法什么也不做;如果用戶瀏覽器禁用了Cookie,則重寫方法在每個URL地址中攜帶JSESSIONID,服務器保證了一個用戶的每一個請求行為攜帶SessionID,從而保證Session的作用。
             Session的invalidate()方法使Session立刻失效。
             可以在項目的web.xml中配置Session失效時間。
 
 
四、Servlet高級特性--過濾器
        1、過濾器概述:
         過濾器是Servlet2.3規范新增的功能,也是Servlet容器管理的對象,其結構同Servlet很類似,比如init()方法,destory()方法, 但是功能不同,過濾器主要是在源數據與目的數據之間起過濾作用的中間組件。
        2、過濾器鏈
         在一個Web應用中,可以一次編寫多個過濾器,這些過濾器組合起來,稱為一個過濾器鏈,其執行順序為注冊順序,先注冊的會先執行
        3、編碼轉換過濾器
          在JavaWeb開發中,初學者經常會遇到java亂碼的問題,統一字符編碼,是解決亂碼問題非常有效的手段,在Web開發中,可以使用過濾器對請求中的參數信息進行編碼轉換。
        4、權限校驗過濾器(清楚整個處理流程)
           根據不同的權限,用戶分別能夠訪問不同的頁面。
 
 






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM