天天看點

【HM】第8課:Request與Response詳解

<pre>

day08

昨天内容回顧

         (1)servlet三種實作的方式

         (2)servlet的生命周期

                   *三個方法 init service  destroy

         (3)URL-Pattern的配置有三種

         (4)路徑的問題

                   *絕對路徑 /day09/....

                   *重定向和轉發

         (5)ServletConfig對象

                   *初始化參數的配置

                   <init-param>

                            <param-name>

                            <param-value>

                   .....

         (6)ServletContext對象

                   *第一,擷取全局初始化參數

                   *第二,域對象,存值和取值

                   *第三,讀取web項目中檔案

                            *路徑:第一個位置是固定/,後面寫檔案在tomcat裡面具體路徑的位址

         (7)類的加載器來讀檔案

                   *如何得到類加載器:

                   **首先Class類

                   **使用Class類裡面方法

         (8)反射的原理

 思維導圖

<a href="http://s3.51cto.com/wyfs02/M00/6F/48/wKiom1WWnDvBROT4AAHF4E_dpfI341.jpg" target="_blank"></a>

今天學習servlet裡面兩個對象一個是請求的對象request,一個是響應的對象response

請求:打開浏覽器輸入一個位址,點選回車,這個過程稱為一個請求

響應:伺服器根據發送的請求,傳回内容顯示到浏覽器的頁面上,這個過程稱為響應

1、響應的對象 HttpServletResponse

         *通過api檢視這個對象,在javax.servlet.http包裡面,是一個接口,父接口是ServletResponse

         *http響應組成

         第一,響應行

                   *設定狀态碼 setStatus(int sc)

                            =setStatus(302);

                   常見狀态碼

                   200  302 304  404  500 503

         第二,響應頭

                   *結構:key-value形式,可以有一個key和一個value,一個key多個value

                   *設定響應頭的方法:

                   setHeader(Stringname, String value)

                   **針對一個key和一個value的情況

                   ***setHeader("aa","123");

                       setHeader("aa","456");

                       結果:名稱是aa,值是456

                   針對特殊的類型設定頭的方法:

                   setIntHeader(Stringname, int value)

                   setDateHeader(Stringname, long date) :值是毫秒數,從1970年1月1日至今的毫秒數

                   addHeader(Stringname, String value)

                   **針對一個key和多個value的情況

                   ***addHeader("bb","444");

                       addHeader("bb","555");

                       結果:名稱bb,值是 444,555

                   addIntHeader(Stringname, int value)

                   addDateHeader(Stringname, long date)

         第三,響應體

                   *什麼是響應體:在頁面上顯示的内容

                   *有兩種方法向頁面輸出内容

                   第一種:getOutputStream()使用位元組流

                   第二種:getWriter()使用字元流

2、案例一:使用response的重定向完成登入的操作

         *需求的描述:首先登入頁面,輸入使用者名和密碼,如果使用者名和密碼正确,向頁面輸出一個成功的資訊;

         如果使用者名或者密碼錯誤,重定向到登入頁面

         *重定向:使用狀态碼是 302,重定向需要使用到一個響應的頭資訊 Location

         **response.setHeader("Location", "重定向到的路徑,使用絕對路徑");

         *具體操作:

         (1)建立一個登入頁面(兩個輸入框,分别是使用者名和密碼;有表單,使用表單送出到一個servlet裡面)

         (2)建立login的servlet

                   *在servlet裡面首先得到輸入的使用者名和密碼

                   *判斷使用者名和密碼是否正确(使用者名和密碼值是固定 admin  123456)

                   *如果使用者名和密碼都正确,表示驗證成功,向頁面輸出success

                   *使用者名或者密碼有一個錯誤,驗證失敗,重定向到登入頁面

         *代碼

                   //得到輸入的使用者名和密碼

                   Stringusername = request.getParameter("username");

                   Stringpassword = request.getParameter("password");

                   //判斷使用者名 admin ,密碼 123456

                   if("admin".equals(username)&amp;&amp; "123456".equals(password)) {//驗證成功

                            //向頁面輸出success

                            response.getWriter().write("success");

                   }else {

                            //重定向到登入頁面

                            //設定狀态碼

                            response.setStatus(302);

                            //設定頭Location

                            response.setHeader("Location","/day08/response/login.html");

                   }

3、案例二:使用response實作頁面的定時跳轉

         (1)需要使用到一個頭資訊Refresh

         *設定頭資訊,使用方法 

         **response.setHeader("Refresh","秒數;url=跳轉到的路徑");

         //使用頭資訊 Refresh

         response.setHeader("Refresh","5;url=/day08/response/login.html");

         (2)實作倒計時的效果

         *代碼:

         //在html裡面可以使用頭标簽meta标簽可以實作類似setHeader方法實作的效果

          &lt;meta http-equiv="Refresh"content="5;url=/day08/response/login.html"&gt;

         //使用js實作倒計時的效果

                //每一秒向span标簽裡面寫一個值

                //setInterval("js",毫秒數)

                var m = 5;

                function load1() {

                         //得到span

                         var span1 =document.getElementById("spanid");

                         span1.innerHTML = m;

                         m--;

                }

                setInterval("load1();",1000);

4、response向頁面輸出中文亂碼問題的解決(****)

         *使用response向頁面輸出内容:

         第一種:getOutputStream()使用位元組流向頁面輸出中文

          * 使用位元組流向頁面輸出中文,是否會有亂碼?

          * 不一定,與浏覽器的編碼有關

          * 解決亂碼問題方式:

          * 1、設定浏覽器的預設的編碼

          * 2、設定位元組數組的編碼

          * 最終,浏覽器的編碼和位元組數組的編碼一樣,不會有亂碼

          ** 代碼

                 //設定浏覽器的編碼 使用到頭資訊content-type

                   response.setHeader("Content-Type","text/html;charset=utf-8");

                   //設定位元組數組的編碼

                   //向頁面輸出中文

                   response.getOutputStream().write("位元組流中文".getBytes("utf-8"));

         第二種:getWriter()使用字元流向頁面輸出中文

          * 使用字元流向頁面輸出中文,是否會有亂碼?

          * 一定會

          *

          * 字元流輸出中文亂碼的解決方式:

          * 輸出機制:在response裡面有輸出的緩沖區,先把内容放到response緩沖區,通過緩沖區進行輸出

          * response緩沖區有預設的編碼,是iso8859-1,不支援中文,輸出時候肯定會有亂碼。

          * 1、設定response緩沖區的編碼(支援中文的編碼)

          * 2、設定浏覽器的編碼

                 //設定response緩沖區的編碼

                   response.setCharacterEncoding("utf-8");

                   //設定浏覽器的編碼

                   response.getWriter().write("字元流中文");

          ** 簡寫方式:相當于設定了緩沖區的編碼,也設定了浏覽器的編碼

                   response.setContentType("text/html;charset=utf-8");

5、注意的地方

         (1)位元組流和字元流不能在一起使用(互斥)

         (2)不能使用字元流直接向頁面輸出數字

         (3)重定向的操作簡寫方式

                   =response.sendRedirect("/day08/response/login.html");

6、案例三:使用response實作檔案的下載下傳

         *基本步驟

         **首先在伺服器上有一個可以下載下傳的檔案

         **把伺服器上的檔案儲存到本地磁盤

                   ***拿到伺服器上面的檔案

                   ***把檔案輸入流儲存到本地硬碟(使用response把檔案流寫到浏覽器)

         *在做檔案下載下傳時候,需要一個頭資訊 Content-Disposititon,如果不設定這個頭,如果是圖檔格式,

         在浏覽器裡面直接打開,這種這個頭的目的就是無論是什麼格式,都以下載下傳的方式打開。

         *如果下載下傳的檔案名稱包含中文,會有問題(到10天時候詳細講檔案上傳和下載下傳)

         **設定編碼方式,不同的浏覽器需要不同的設定方式(ie和火狐)

         ***ie浏覽器采用的編碼方式url編碼,隻有把中文檔案名稱進行url編碼才可以正常顯示

         **代碼

                   //得到檔案的完全路徑

                   Stringpath = getServletContext().getRealPath("/img/a.jpg");

//               System.out.println(path);

                   //I:\0621\apache-tomcat-7.0.53\webapps\day08\img\a.jpg

                   //先找到最後/位置,位置進行截取

                   intlens = path.lastIndexOf("\\");             

                   Stringfilename = path.substring(lens+1);

//               System.out.println(filename);

                   //設定頭資訊

                   response.setHeader("Content-Disposition","attachment;filename="+filename);

                   //從伺服器上拿到檔案

                   InputStreamin = new FileInputStream(path);

                   //使用輸出流把檔案寫到浏覽器

                   OutputStreamout = response.getOutputStream();

                   //流的對接

                   intlen = 0;

                   byte[]b = new byte[1024];

                   while((len=in.read(b))!=-1){

                            out.write(b,0, len);

                   //關閉流

                   in.close();

7、使用response實作驗證碼的開發

         *驗證碼:防止惡意注冊....

=========================================================================

         上午内容的總結

         (1)response對象對應http響應裡面方法

                   *響應行  響應頭  響應體

         (2)案例一:使用Response實作登入重定向

                   *如何實作重定向操作 302+location

                   *重定向簡寫方式

         (3)案例二:使用Response實作頁面定時重新整理

                   *使用頭Refresh實作定時跳轉

                   *使用js實作倒計時效果

         (4)使用response向頁面輸出中文亂碼解決(***)

                   *位元組流

                   *字元流

         (5)案例三:使用Response實作檔案的下載下傳

                   *檔案下載下傳的步驟(設定頭資訊 Content-Disposition)

                   *檔案下載下傳的代碼

8、中文驗證碼和驗證碼寫在登入頁面

9、request對象代表請求,HttpServletRequest的父接口是ServletRequest

         (1)擷取客戶機的資訊

         *getMethod():擷取表單送出的方式(get或者post或者其他...)

         *getContextPath() 擷取目前項目的名稱

         *getRemoteAddr() 擷取目前請求的ip位址

         (2)擷取請求的頭資訊

         *重要的頭 Referer、User-Agent

         *getHeader(String name) :擷取請求頭資訊

         (3)擷取表單送出的資料

         *方法

         *getParameter(String name):得到表單送出的資料,參數是表單輸入項的name的值

                   =//getParameter(String name)方法的使用

         *String[] getParameterValues(String name):得到多個輸入項的值,一般使用在複選框的情況下

                   =//getParameterValues(String name) 擷取複選框的值

                   String[]loves = request.getParameterValues("love");

                   System.out.println(Arrays.toString(loves));

         *Map getParameterMap() :傳回map集合,map是key-value結構,

                   key就是表單輸入項的name的值,value是輸入的值

                   =//getParameterMap()

                   Map&lt;String,String[]&gt;map = request.getParameterMap();

                   //周遊

                   //得到所有的key

                   Set&lt;String&gt;keys = map.keySet();

                   for(String key : keys) {

                            //根據key得到value

                            String[]values = map.get(key);

                            System.out.println("key:"+key+":: value:"+Arrays.toString(values));

         *Enumeration getParameterNames()  :擷取所有的表單輸入項的name的值

         (4)使用表單送出資料包含中文問題解決

         *當送出資料裡面有中文,會有中文亂碼的

         *解決:

         **分别處理get送出和post送出

         ***post送出資料有中文

                   *設定request緩沖區的編碼

                    * 使用post送出資料放到request緩沖區裡面,request緩沖區的編碼是iso8859-1

                    * * 解決方法:設定request緩沖區的編碼解決post送出中文亂碼的問題

         ***get送出資料有中文

         **有三種解決方法

         解決方案一:修改server.xml

                   &lt;Connectorport="80" protocol="HTTP/1.1"      

                   connectionTimeout="20000"redirectPort="8443" URIEncoding="utf-8"/&gt;

         *必須有修改tomcat伺服器配置檔案權限

         解決方案二:逆向編解碼

            username = URLEncoder.encode(username,"ISO8859-1");

            username = URLDecoder.decode(username,"utf-8");

         解決方案三:簡化(重點記住)

         username= new String(username.getBytes("ISO8859-1"),"utf-8");

         Stringgetusername = request.getParameter("getusername");

         getusername= new String(getusername.getBytes("iso8859-1"),"utf-8");

         (5)request域對象

         *之前學過servletContext域對象,範圍是整個的web項目

         *request也是一個域對象,範圍是一次請求,存值和取值

                   =存值:setAttribute(String name, Object o)

                   =取值:getAttribute(String name)

         *經常和轉發在一起使用

                   *使用request實作轉發的代碼

                   request.getRequestDispatcher("轉發的路徑,不帶項目名稱").forward();

         *舉例說明request域

         **建立一個servlet1,向request域裡面設定一個值,同時轉發到servlet2裡面去

         **建立servlet2,在servlet2裡面擷取request域對象裡面的值

         *重定向和轉發

         *重定向:從一個系統到另外一個系統

         *轉發:做跳轉操作時候需要攜帶資料

案例六:使用轉發重寫登入案例

         *需求描述:當輸入正确使用者名和密碼,向頁面輸出success

         如果輸入的使用者名或者密碼有錯誤,轉發到登入頁面,同時在頁面中顯示錯誤資訊

         *引入知識:

         *jsp:jsp最終會被編譯成servlet,在jsp裡面可以寫java代碼

         *el表達式:擷取域對象裡面的值,一般使用在jsp頁面中

                   **${域對象名稱}

======================================================================

         今天内容的總結

         (1)response

         *response裡面對應http協定裡面的對應的方法

         *在response裡面做了四個案例(不包含驗證碼)代碼至少寫三遍

         *驗證碼的案例,看懂就可以了。

         *重點掌握看不清換一張實作

         *Response向頁面輸出中文亂碼解決(****)

         (2)request

         *擷取客戶機資訊和頭資訊的方法

         *擷取表單送出的資料

         *擷取表單送出中文資料亂碼問題解決(****)

         *request域

         *重定向和轉發的差別

&lt;/pre&gt;

      本文轉自屠夫章哥  51CTO部落格,原文連結:http://blog.51cto.com/4259297/1670706,如需轉載請自行聯系原作者