javaWeb之ServletConfig&ServletContext

1. ServletConfig對象.
    概述: 當前Servlet的配置信息對象.

    作用: 可以讀取當前Servlet對象的配置信息.

    需求:  Java代碼中涉及到配置參數了, 如何修改配置參數?
        傳統方式:
            1) 修改Java代碼. (開發環境中實現)                              //開發環境中實現
            2) 將項目打成war包(JavaWeb應用程序包, 能被tomcat服務器識別).  //開發環境中實現
            3) 將war包拷貝到生產環境(機房, 服務器)                        
            4) 啓動項目.                                                    //生產環境中實現
            //這樣做和開發原則"對修改關閉, 對擴展開放"相違背.

        結合配置文件的方式:
            1) 修改配置文件的內容.
            2) 重啓項目.


    背景: 
        實際開發中, 我們會把項目相關的配置屬性寫入到配置文件中, 
        這樣當配置屬性的值發生改變時, 我們只需要修改配置文件, 
        重啓服務即可. 


    實現步驟:
        1) 將當前servlet配置信息放到web.xml中.
            //設置當前Servlet對象的配置信息, 該標籤可以寫多組.
            <init-param>
                <param-name>屬性名</param-name>
                <param-value>屬性值</param-value>
            </init-param>
            <init-param>
                <param-name>size</param-name>
                <param-value>250</param-value>
            </init-param>
        2) 服務器將配置信息放到servletConfig中.
        3) 將ServletConfig傳給Servlet.
        4) 在servlet中就可以通過 this.getServletConfig()方法獲取
           ServletConfig對象的引用, 進而獲取配置信息.
            ServletConfig sc = getServletConfig();
            //獲取指定屬性名對應的值.
            String str = sc.getInitParameter("屬性名");       

    特點:
        每個Servlet都會有一個ServletConfig對象.



    總結: ServletConfig接口中的方法
        public String getInitParameter(String name);    //根據參數名獲取其值
        public Enumeration<String> getInitParameterNames(); //獲取所有的參數名


2. ServletContext對象: 獲取當前項目的參數信息
    ServletContext對象:       //記憶
        和tomcat中的項目是一一對應的, 一個項目就會有一個ServletContext對象.

    作用: 
        可以讀取當前項目的參數信息.

    步驟:
        1) 把項目的配置參數寫入到當前項目下的: web.xml文件中.
              //設置當前項目的配置信息, 可以寫多組.
              <context-param>
                <param-name>gongsi</param-name>
                <param-value>百度</param-value>
              </context-param>
              <context-param>
                <param-name>jingli</param-name>
                <param-value>李彥宏</param-value>
              </context-param>
        2) 獲取當前項目的配置信息


3. ServletContext對象的應用之: 當做容器來使用.

    應用場景:
        1) 每個servlet中都可以通過ServletContext對象獲取當前項目在web.xml中配置的參數信息.

        2) 多個servlet可以將ServletContext對象當做一個容器去使用, 爲什麼?
            "容器" --> "域"
            //大白話   專業名詞

        3) 通過ServletContext對象可以獲取項目內資源的絕對路徑.

        4) 通過ServletContext對象可以獲取項目內資源的類型

        5) 通過ServletContext對象可以獲取項目名


    案例演示:  ServletContext對象的應用場景(2) 
        /*
            一個ServletContext對象獲取訪問的ip地址, 保存到context容器中.
                //獲取瀏覽器請求時的ip, 調用ServletRequest#getRemoteAddr();
                String ip = request.getRemoteAddr();
            另一個ServletContext對象從context容器中讀取出該IP.
        */

    ServletContext中的方法:
        public String getInitParameter(String name);    //根據參數名獲取其值
        public Enumeration<String> getInitParameterNames(); //獲取所有的參數名

        public Object getAttribute(String name);    //根據屬性名, 獲取其值.
        public void setAttribute(String name,Object value); //設置屬性
        public void removeAttribute(String name);   //根據屬性名, 移除該屬性.




    結論:
        ServletContext對象當做容器這種使用方式, 以後開發中儘量不要使用,
        因爲ServletContext對象是和項目對應的, 如果項目負擔過大, 將會影響
        用戶的體驗.



4. ServletContext對象的其他應用
    ServletContext接口中的方法:
        public String getRealPath(String filePath); //獲取資源文件的絕對路徑.
        public String getMimeType(String fileName); //獲取資源文件的類型
        public String getContextPath();             //獲取當前項目的項目名.
        //也可以通過: String name = request.getContextPath(); 的方式獲取項目名


5. http協議:
    概述: 
        超文本傳輸協議(HyperText Transfer Protocol)是,瀏覽器和服務器之間進行交互的規則.
        由請求和響應組成.

        請求: //瀏覽器向服務器傳輸的數據, request
            由三部分組成, 分別爲:
                請求行: 
                請求頭: 
                請求體:    //get請求沒有請求體, post請求有請求體.



        響應: //服務器向瀏覽器回送的數據, response
            由三部分組成, 分別爲:
                響應行: 
                響應頭: 
                響應體: 

    案例: 檢驗請求和響應的組成.
        1) 谷歌和火狐瀏覽器的F12就可以, 但是不適合教學, 適合開發.
        2) IE瀏覽器安裝httpwatch插件, 適合教學, 因爲比較直觀.


6. 訪問Servlet的細節圖:
    1) 瀏覽器向服務器發送數據.
        請求行, 請求頭, 請求體(post方式有, get方式沒有)
    2) 服務器解析瀏覽器發送的數據.
        //解析請求
    3) 創建Servlet對象.
    4) 創建request對象和response對象.
        request對象:  //封裝瀏覽器給服務器的所有數據
        response對象: //封裝服務器給瀏覽器的所有數據
    5) 在service()方法中, 將request和response對象作爲參數傳給servlet對象.
    6) 將給瀏覽器的數據全部放到response對象中.
    7) 解析response對象.
        //響應行, 響應頭, 響應體
    8) 解析數據, 展示對應的內容.



7. 獲取請求行數據
    Request對象的方法:
        public String getMethod();      //獲取請求的方式
        public String getRequestURI();  //獲取請求資源
        public String getProtocol();    //獲取協議類型
        public String getContextPath(); //獲取項目名(項目路徑)
        public String getRemoteAddr();  //獲取IP地址.
        public int getLocalPort();      //獲取端口號


8. 獲取請求頭數據
    Request對象的方法:
        public String getHeader(String name);   //根據給定name名獲取其對應的值
            //獲取 HOST + User Agent等信息
        public Enumeration getHeaderNames();    //獲取所有的請求頭的屬性名

9. 解決get方式的中文亂碼問題
    原因:
        1) 瀏覽器先對數據進行"utf-8"編碼, 然後發送給服務器.
            //瀏覽器的默認編碼格式是"gbk", 但是我們Eclipse的工作空間已經改爲
            //UTF-8碼錶了, 所以創建在Eclipse中的頁面也是採用"utf-8"碼錶.
        2) 服務器接收到瀏覽器發送的數據後, 按照"iso-8859-1"碼錶解碼.
        3) 服務器將"亂碼"後的數據傳輸給: Servlet對象.
        4) 此時, Servlet對象從服務器獲取的數據肯定是亂碼的.

    解決方案:
        方案一: 把服務器的默認碼錶改爲"utf-8".    
            //不推薦, 因爲有可能項目不是這個餓嗎表.

        方式二: 先編碼, 再解碼.
            方案一:  //通過URLEncoder#encode(), URLDecoder#decode()
                1) Servlet對象先對服務器傳過來的數據進行"iso-8859-1"編碼.
                    //這樣做的目的是將數據 還原到 瀏覽器傳輸給服務器的原始狀態.
                    String str = URLEncoder.encode("要編碼的字符串","指定的碼錶");

                2) 然後對編碼後的數據進行"utf-8"解碼操作即可.
                    String str = URLDecoder.decode("要解碼的字符串","指定的碼錶");

            方案二: 通過String類的功能實現
                public byte[] getBytes("指定的碼錶");    
                    //將字符串轉成指定碼錶的 字節數組形式.
                public String(byte[] bys,String charsetName);
                    //將字節數組按照指定的碼錶轉成其對應的 字符串形式.


10. 解決post方式的中文亂碼問題
    方式一: 和(9)裏邊標註的方式一樣.


    方式二:  該方式只針對post有效(因爲該方式是針對於請求體的, post有請求體)
        //設置客戶端對請求體進行"utf-8"碼錶編碼
        request.setCharacterEncoding("utf-8");


11. 請求轉發原理圖
    目前我們知道的"頁面跳轉"的方式:(下述這些都是HTML和JS的)
        <a>, <form>, BOM對象之Location.href, Window對象的open()
    那麼Java代碼中能不能完成"頁面跳轉"的功能呢?
        接下來我們要學習的"請求轉發"就是Java代碼進行"頁面跳轉"的一種方式.

    原理思路:
        1) 瀏覽器給服務器發送數據, 服務器把數據給到RequestServlet1.
        2) RequestServlet1把Request,Response兩大對象傳給RequestServlet2.
        3) 由RequestServlet2完成數據的處理, 然後把數據傳輸給瀏覽器.



12. 請求轉發實現頁面跳轉
    要轉發的RequestServlet對象.
        1) 將IP地址保存到request容器中.
            request.setAttribute("ip",request.gerRemoteAddr());

        2) 獲取請求轉發對象.
            RequestDispatcher rd = request.getRequestDispatcher("要轉發的路徑");
            //例如:  request.getRequestDispatcher("/requestServlet2");
        3) 執行轉發動作.
            rd.forward(request對象, response對象);
        4) 使用return結束.  //可寫可不寫, 建議寫上.
            return;


    被轉發的RequestServlet對象.
        1) 從request容器中取出ip地址, 打印到瀏覽器中
            String ip = (String)request.getAttribute("ip");

        2) 把獲取到的ip, 打印到瀏覽器中即可.


    請求轉發的
        特徵:
            瀏覽器訪問的是Demo1Servlet, 但是給你響應內容的是: Demo2Servlet.

        注意: //記憶
            1) 每次請求都會創建新的request對象和response對象.
            2) 每次響應結束後, request對象和response對象就會被立刻銷燬.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章