小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

JavaWeb之Request對(duì)象和Response對(duì)象詳解

 沙門(mén)空海 2017-09-12


一:概述

Web服務(wù)器收到客戶(hù)端的http請(qǐng)求,會(huì)針對(duì)每一次請(qǐng)求,分別創(chuàng)建一個(gè)用于代表請(qǐng)求的request對(duì)象、和代表響應(yīng)的response對(duì)象

一、Response對(duì)象
    
1.Resonse的繼承結(jié)構(gòu):
            ServletResponse--HttpServletResponse
    2.Response代表響應(yīng),于是響應(yīng)消息中的 狀態(tài)碼、響應(yīng)頭、實(shí)體內(nèi)容都可以由它進(jìn)行操作,由此引伸出如下實(shí)驗(yàn):
    3.利用Response輸出數(shù)據(jù)到客戶(hù)端
        response.getOutputStream().write('中文'.getBytes())輸出數(shù)據(jù),這是一個(gè)字節(jié)流,寫(xiě)入內(nèi)存使用什么編碼,輸出就使用什么編碼,而瀏覽器默認(rèn)用平臺(tái)字節(jié)碼打開(kāi)服務(wù)器發(fā)送的數(shù)據(jù),如果服務(wù)器端使用了非平臺(tái)碼去輸出字符的字節(jié)數(shù)據(jù)就需要明確的指定瀏覽器編碼時(shí)所用的碼表,以防止亂碼問(wèn)題。

       response.addHeader('Content-type','text/html;charset=gb2312')
       response.getWriter().write(“中文”);輸出數(shù)據(jù),這是一個(gè)字符流,response會(huì)將此字符進(jìn)行轉(zhuǎn)碼操作后輸出到瀏覽器,這個(gè)過(guò)程默認(rèn)使用ISO8859-1碼表,而ISO8859-1中沒(méi)有中文,于是轉(zhuǎn)碼過(guò)程中用?代替了中文,導(dǎo)致亂碼問(wèn)題??梢灾付╮esponse在轉(zhuǎn)碼過(guò)程中使用的目標(biāo)碼表,防止亂碼。response.setCharacterEncoding('gb2312');
        其實(shí)response還提供了setContentType('text/html;charset=gb2312')方法,此方法會(huì)設(shè)置content-type響應(yīng)頭,通知瀏覽器打開(kāi)的碼表,同時(shí)設(shè)置response的轉(zhuǎn)碼時(shí)使的用碼表,從而一行代碼解決亂碼。
    4.利用Response 設(shè)置 content-disposition頭實(shí)現(xiàn)文件下載
            設(shè)置響應(yīng)頭content-disposition為“attachment;filename=xxx.xxx”
            利用流將文件讀取進(jìn)來(lái),再利用Response獲取響應(yīng)流輸出
            如果文件名為中,一定要進(jìn)行URL編碼,編碼所用的碼表一定要是UTF-8
    5.refresh頭控制定時(shí)刷新
        設(shè)置響應(yīng)頭Refresh為一個(gè)數(shù)值,指定多少秒后刷新當(dāng)前頁(yè)面
        設(shè)置響應(yīng)頭Refresh為 3;url=/Day05/index.jsp,指定多少秒后刷新到哪個(gè)頁(yè)面
        可以用來(lái)實(shí)現(xiàn)注冊(cè)后“注冊(cè)成功,3秒后跳轉(zhuǎn)到主頁(yè)”的功能
        在HTML可以利用標(biāo)簽?zāi)M響應(yīng)頭的功能。

      eg:
    6.利用response設(shè)置expires、Cache-Control、Pragma實(shí)現(xiàn)瀏覽器是否緩存資源,這三個(gè)頭都可以實(shí)現(xiàn),但是由于歷史原因,不同瀏覽器實(shí)現(xiàn)不同,所以一般配合這三個(gè)頭使用
        6.1控制瀏覽器不要緩存(驗(yàn)證碼圖片不緩存)設(shè)置expires為0或-1設(shè)置Cache-Control為no-cache、Pragma為no-cache
        6.2控制瀏覽器緩存資源。即使不明確指定瀏覽器也會(huì)緩存資源,這種緩存沒(méi)有截至日期。當(dāng)在地址欄重新輸入地址時(shí)會(huì)用緩存,但是當(dāng)刷新或重新開(kāi)瀏覽器訪(fǎng)問(wèn)時(shí)會(huì)重新獲得資源。
            如果明確指定緩存時(shí)間,瀏覽器緩存是,會(huì)有一個(gè)截至日期,在截至日期到期之前,當(dāng)在地址欄重新輸入地址或重新開(kāi)瀏覽器訪(fǎng)問(wèn)時(shí)都會(huì)用緩存,而當(dāng)刷新時(shí)會(huì)重新獲得資源。
    7.Response實(shí)現(xiàn)請(qǐng)求重定向
        7.1古老方法:response.setStatus(302);response.addHeader('Location','URL');
        7.2快捷方式:response.sendRedirect('URL');
  
    8.Response注意的內(nèi)容:
        8.1對(duì)于一次請(qǐng)求,Response的getOutputStream方法和getWriter方法是互斥,只能調(diào)用其一,特別注意forward后也不要違反這一規(guī)則。
        8.2利用Response輸出數(shù)據(jù)的時(shí)候,并不是直接將數(shù)據(jù)寫(xiě)給瀏覽器,而是寫(xiě)到了Response的緩沖區(qū)中,等到整個(gè)service方法返回后,由服務(wù)器拿出response中的信息組成響應(yīng)消息返回給瀏覽器。
        8.3service方法返回后,服務(wù)器會(huì)自己檢查Response獲取的OutputStream或者Writer是否關(guān)閉,如果沒(méi)有關(guān)閉,服務(wù)器自動(dòng)幫你關(guān)閉,一般情況下不要自己關(guān)閉這兩個(gè)流。
        

二、Request:Request代表請(qǐng)求對(duì)象,其中封裝了對(duì)請(qǐng)求中具有請(qǐng)求行、請(qǐng)求頭、實(shí)體內(nèi)容的操作的方法
    1.獲取客戶(hù)機(jī)信息
        getRequestURL方法返回客戶(hù)端發(fā)出請(qǐng)求完整URL    eg:返回: ' http://localhost:8080/Day05/index.jsp'
        getRequestURI方法返回請(qǐng)求行中的資源名部分,在權(quán)限控制中常用 eg:返回  '/Day05/index.jsp'
        getQueryString 方法返回請(qǐng)求行中的參數(shù)部分
        getRemoteAddr方法返回發(fā)出請(qǐng)求的客戶(hù)機(jī)的IP地址
        getMethod得到客戶(hù)機(jī)請(qǐng)求方式
        getContextPath 獲得當(dāng)前web應(yīng)用虛擬目錄名稱(chēng),特別重要?。?!,工程中所有的路徑請(qǐng)不要硬編碼(不要寫(xiě)死),其中的web應(yīng)用名要以此方法去獲得。

    2.獲取請(qǐng)求頭信息
        getHeader(name)方法 --- String ,獲取指定名稱(chēng)的請(qǐng)求頭的值
        getHeaders(String name)方法 --- Enumeration ,獲取指定名稱(chēng)的請(qǐng)求頭的值的集合,因?yàn)榭赡艹霈F(xiàn)多個(gè)重名的請(qǐng)求頭
        getHeaderNames方法 --- Enumeration ,獲取所有請(qǐng)求頭名稱(chēng)組成的集合
        getIntHeader(name)方法  --- int ,獲取int類(lèi)型的請(qǐng)求頭的值
        getDateHeader(name)方法 --- long(日期對(duì)應(yīng)毫秒) ,獲取一個(gè)日期型的請(qǐng)求頭的值,返回的是一個(gè)long值,從1970年1月1日0時(shí)開(kāi)始的毫秒值
        
        *實(shí)驗(yàn):通過(guò)referer信息防盜鏈(防盜鏈:非正常訪(fǎng)問(wèn),簡(jiǎn)單的是,就是不是從規(guī)定的站點(diǎn)發(fā)送HTTP請(qǐng)求,而是從其他站點(diǎn)發(fā)送的HTTP請(qǐng)求)
            String ref = request.getHeader('Referer');
            if (ref == null || ref == '' || !ref.startsWith('http://localhost')) {
                response.sendRedirect(request.getContextPath() + '/homePage.html');
            } else {
                //為了不讓其他資源可見(jiàn),fengjie.html應(yīng)該存放在WEB-INF目錄下
                this.getServletContext().getRequestDispatcher('/WEB-INF/fengjie.html').forward(request, response);
            }
    3.獲取請(qǐng)求參數(shù)
        getParameter(name) --- String 通過(guò)name獲得值
        getParameterValues(name)  --- String[ ] 通過(guò)name獲得多值 checkbox
        getParameterNames  --- Enumeration 獲得所有請(qǐng)求參數(shù)名稱(chēng)組成的枚舉
        getParameterMap  --- Map 獲取所有請(qǐng)求參數(shù)的組成的Map集合,注意,其中的鍵為String,值為String[]
        
        獲取請(qǐng)求參數(shù)時(shí)亂碼問(wèn)題:
            瀏覽器發(fā)送的請(qǐng)求參數(shù)使用什么編碼呢?當(dāng)初瀏覽器打開(kāi)網(wǎng)頁(yè)時(shí)使用什么編碼,發(fā)送就用什么編碼。
            服務(wù)器端獲取到發(fā)過(guò)來(lái)的請(qǐng)求參數(shù)默認(rèn)使用ISO8859-1進(jìn)行解碼操作,中文一定有亂碼問(wèn)題
            對(duì)于Post方式提交的數(shù)據(jù),可以設(shè)置request.setCharacterEncoding('gb2312');來(lái)明確指定獲取請(qǐng)求參數(shù)時(shí)使用編碼。但是此種方式只對(duì)Post方式提交有效。
            對(duì)于Get方式提交的數(shù)據(jù),就只能手動(dòng)解決亂碼:String newName = new String(name.getBytes('ISO8859-1'),'gb2312');此種方法對(duì)Post方式同樣有效。
            request.setCharacterEncoding('gb2312');對(duì)GET方式提交無(wú)效的原因是:該代碼只設(shè)置請(qǐng)求實(shí)體的編碼,而GET提交的數(shù)據(jù)是存放在請(qǐng)求行中的[資源名?param1='張三'¶m2=123],所以對(duì)GET請(qǐng)求的方式無(wú)效。
            在tomcat的server.xml中可以配置http連接器的URIEncoding可以指定服務(wù)器在獲取請(qǐng)求參數(shù)時(shí)默認(rèn)使用的編碼,從而一勞永逸的決絕獲取請(qǐng)求參數(shù)時(shí)的亂碼問(wèn)題。也可以指定useBodyEncodingForURI參數(shù),令request.setCharacterEncoding也對(duì)GET方式的請(qǐng)求起作用,但是這倆屬性都不推薦使用,因?yàn)榘l(fā)布環(huán)境往往不允許修改此屬性。
            
            
    4.利用請(qǐng)求域傳遞對(duì)象
        生命周期:在service方法調(diào)用之前由服務(wù)器創(chuàng)建,傳入service方法。整個(gè)請(qǐng)求結(jié)束,request生命結(jié)束。
        作用范圍:整個(gè)請(qǐng)求鏈。
        作用:在整個(gè)請(qǐng)求鏈中共享數(shù)據(jù),最常用的:在Servlet中處理好的數(shù)據(jù)要交給Jsp顯示,此時(shí)參數(shù)就可以放置在Request域中帶過(guò)去。
        
    5.request實(shí)現(xiàn)請(qǐng)求轉(zhuǎn)發(fā)
        ServletContext可以實(shí)現(xiàn)請(qǐng)求轉(zhuǎn)發(fā),request也可以。
        在forward之前輸入到response緩沖區(qū)中的數(shù)據(jù),如果已經(jīng)被發(fā)送到了客戶(hù)端,forward將失敗,拋出異常
        在forward之前輸入到response緩沖區(qū)中的數(shù)據(jù),但是還沒(méi)有發(fā)送到客戶(hù)端,forward可以執(zhí)行,但是緩沖區(qū)將被清空,之前的數(shù)據(jù)丟失。注意丟失的只是請(qǐng)求體中的內(nèi)容,頭內(nèi)容仍然有效。
        在一個(gè)Servlet中進(jìn)行多次forward也是不行的,因?yàn)榈谝淮蝔orward結(jié)束,response已經(jīng)被提交了,沒(méi)有機(jī)會(huì)再forward了
        總之,一條原則,一次請(qǐng)求只能有一次響應(yīng),響應(yīng)提交走后,就再?zèng)]有機(jī)會(huì)輸出數(shù)據(jù)給瀏覽器了。
        
    6.RequestDispatcher進(jìn)行include操作
        forward沒(méi)有辦法將多個(gè)servlet的輸出組成一個(gè)輸出,因此RequestDispatcher提供了include方法,可以將多個(gè)Servlet的輸出組成一個(gè)輸出返回個(gè)瀏覽器
            request.getRequestDispatcher('/servlet/Demo17Servlet').include(request, response);
            response.getWriter().write('from Demo16');
            request.getRequestDispatcher('/servlet/Demo18Servlet').include(request, response);
        常用在頁(yè)面的固定部分單獨(dú)寫(xiě)入一個(gè)文件,在多個(gè)頁(yè)面中include進(jìn)來(lái)簡(jiǎn)化代碼量。
        
        

三、地址的寫(xiě)法:

絕對(duì)路徑(以斜線(xiàn)開(kāi)頭的路徑,代表相對(duì)與當(dāng)前web應(yīng)用):
    如果地址是給服務(wù)器用的,web應(yīng)用的名稱(chēng)可以省略。如果地址是給客戶(hù)端用的,必須寫(xiě)上web應(yīng)用名
    request.getRequestDispatcher('/index.jsp').include(request, response);
    response.setHeader('Location','/Day05/index.jsp');
    response.sendRedirect('/Day05/index.jsp');
    this.getServletContext().getRealPath('/index.jsp');
    this.getServletContext().getResourceAsStream('/index.jsp');
    
    
    
    類(lèi)加載器加載資源的時(shí)候,相對(duì)于WEB-INF下的classes目錄
    this.getClass().getClassLoader().getResource('');
    this.getClass().getClassLoader().getResourceAsStream('');
相對(duì)路徑(不以斜杠開(kāi)頭的路徑,要參考當(dāng)前所在的路徑去拼新的路徑)---除了在必須使用的情況外,都不要使用相對(duì)路徑:
    如果直接寫(xiě)相對(duì)路徑或?qū)?/相對(duì)路徑的話(huà),相對(duì)路徑替換當(dāng)前路徑最后一級(jí)
    如果寫(xiě)../相對(duì)路徑,則替換當(dāng)前路徑的最后一級(jí)路徑的上一級(jí)路徑。
    如果想替換更高層,則寫(xiě)多個(gè)../
    
四、URL編碼
    1.由于HTTP協(xié)議規(guī)定URL路徑中只能存在ASCII碼中的字符,所以如果URL中存在中文或特殊字符需要進(jìn)行URL編碼。
    2.編碼原理:
        將空格轉(zhuǎn)換為加號(hào)(+)
        對(duì)0-9,a-z,A-Z之間的字符保持不變
        對(duì)于所有其他的字符,用這個(gè)字符的當(dāng)前字符集編碼在內(nèi)存中的十六進(jìn)制格式表示,并在每個(gè)字節(jié)前加上一個(gè)百分號(hào)(%)。如字符“+”用%2B表示,字符“=”用%3D表示,字符“&”用%26表示,每個(gè)中文字符在內(nèi)存中占兩個(gè)字節(jié),字符“中”用%D6%D0表示,字符“國(guó)”用%B9%FA表示,對(duì)于空格也可以直接使用其十六進(jìn)制編碼方式,即用%20表示,而不是將它轉(zhuǎn)換成加號(hào)(+)
        說(shuō)明:
        如果確信URL串的特殊字符沒(méi)有引起使用上的岐義或沖突你也可以對(duì)這些字符不進(jìn)行編碼,而是直接傳遞給服務(wù)器。例如,http://www./dealregister.html?name=中國(guó)&password=123
        如果URL串中的特殊字符可能會(huì)產(chǎn)生岐義或沖突,則必須對(duì)這些特殊字符進(jìn)行URL編碼。例如,服務(wù)器會(huì)將不編碼的“中+國(guó)”當(dāng)作“中國(guó)”處理。還例如,當(dāng)name參數(shù)值為“中&國(guó)”時(shí),如果不對(duì)其中的“&”編碼,URL字符串將有如下形式:http://www./dealregister.html?name=中&國(guó)&password=123,應(yīng)編碼為:http://www./dealregister.html?name=中%26國(guó)&password=123
        http://www./example/index.html#section2可改寫(xiě)成http://www./example%2Findex.html%23section2
    3.在java中進(jìn)行URL編碼和解碼
        URLEncoder.encode('xxxx','utf-8');
        URLDecoder.decode(str,'utf-8');


五、請(qǐng)求重定向和請(qǐng)求轉(zhuǎn)發(fā)的區(qū)別
    1.區(qū)別
            RequestDispatcher.forward方法只能將請(qǐng)求轉(zhuǎn)發(fā)給同一個(gè)WEB應(yīng)用中的組件;而HttpServletResponse.sendRedirect 方法還可以重定向到同一個(gè)站點(diǎn)上的其他應(yīng)用程序中的資源,甚至是使用絕對(duì)URL重定向到其他站點(diǎn)的資源。
            如果傳遞給HttpServletResponse.sendRedirect 方法的相對(duì)URL以“/”開(kāi)頭,它是相對(duì)于服務(wù)器的根目錄;如果創(chuàng)建RequestDispatcher對(duì)象時(shí)指定的相對(duì)URL以“/”開(kāi)頭,它是相對(duì)于當(dāng)前WEB應(yīng)用程序的根目錄。
            調(diào)用HttpServletResponse.sendRedirect方法重定向的訪(fǎng)問(wèn)過(guò)程結(jié)束后,瀏覽器地址欄中顯示的URL會(huì)發(fā)生改變,由初始的URL地址變成重定向的目標(biāo)URL;調(diào)用RequestDispatcher.forward 方法的請(qǐng)求轉(zhuǎn)發(fā)過(guò)程結(jié)束后,瀏覽器地址欄保持初始的URL地址不變。
            HttpServletResponse.sendRedirect方法對(duì)瀏覽器的請(qǐng)求直接作出響應(yīng),響應(yīng)的結(jié)果就是告訴瀏覽器去重新發(fā)出對(duì)另外一個(gè)URL的訪(fǎng)問(wèn)請(qǐng)求;RequestDispatcher.forward方法在服務(wù)器端內(nèi)部將請(qǐng)求轉(zhuǎn)發(fā)給另外一個(gè)資源,瀏覽器只知道發(fā)出了請(qǐng)求并得到了響應(yīng)結(jié)果,并不知道在服務(wù)器程序內(nèi)部發(fā)生了轉(zhuǎn)發(fā)行為。
            RequestDispatcher.forward方法的調(diào)用者與被調(diào)用者之間共享相同的request對(duì)象和response對(duì)象,它們屬于同一個(gè)訪(fǎng)問(wèn)請(qǐng)求和響應(yīng)過(guò)程;而HttpServletResponse.sendRedirect方法調(diào)用者與被調(diào)用者使用各自的request對(duì)象和response對(duì)象,它們屬于兩個(gè)獨(dú)立的訪(fǎng)問(wèn)請(qǐng)求和響應(yīng)過(guò)程。
    2.應(yīng)用場(chǎng)景(參照?qǐng)D想)
        通常情況下都用請(qǐng)求轉(zhuǎn)發(fā),減少服務(wù)器壓力
        當(dāng)需要更新地址欄時(shí)用請(qǐng)求重定向,如注冊(cè)成功后跳轉(zhuǎn)到主頁(yè)。
        當(dāng)需要刷新更新操作時(shí)用請(qǐng)求重定向,如購(gòu)物車(chē)付款的操作。



    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多