day03

response

第1章ServletContext接口

場(chǎng)景:
在線人數(shù):xxx萬,吸引用戶來注冊(cè)。

當(dāng)用戶進(jìn)入系統(tǒng),應(yīng)該當(dāng)前在線人數(shù)加一——servlet處理
當(dāng)用戶退出系統(tǒng),應(yīng)該當(dāng)前在線人數(shù)減一——servlet處理

需求:
有在線人數(shù)的數(shù)據(jù),必須,可以讓兩個(gè)servlet都可以獲取使用。

希望:有這么一個(gè)容器(保存數(shù)據(jù)),這個(gè)容器可以被多個(gè)servlet同時(shí)使用。

這個(gè)就是我們ServletContext容器:


圖片84.png

ServletContext示意圖:他是一個(gè)存儲(chǔ)數(shù)據(jù)的容器

圖片85.png

總結(jié):
1 容器可以存儲(chǔ)數(shù)據(jù)
2 操作容器set get remove
3 可以被多個(gè)Servlet使用共享。

當(dāng)tomcat啟動(dòng)時(shí),會(huì)為每個(gè)web應(yīng)用創(chuàng)建一個(gè)唯一的ServletContext對(duì)象代表當(dāng)前Web應(yīng)用.該對(duì)象不僅封裝了當(dāng)前web應(yīng)用的所有信息,而且實(shí)現(xiàn)了多個(gè)servlet的數(shù)據(jù)共享.
在每個(gè)項(xiàng)目中可以有多個(gè)Servlet程序,每個(gè)Servlet程序都是獨(dú)立的。Servlet中的配置信息可以使用ServletConfig獲取,而當(dāng)前這個(gè)項(xiàng)目的配置信息,就必須使用描述這個(gè)項(xiàng)目的ServletContext對(duì)象獲取。

1.1ServletContext容器的存取刪操作(重點(diǎn))

由于一個(gè)web應(yīng)用程序中的所有Servlet共享同一個(gè)ServletContxt對(duì)象,因此ServletContext中的屬性可以被Web應(yīng)用程序中的所有servlet訪問。在ServletContext中分別定義了用于 增加、刪除、獲取ServletContext屬性的4個(gè)方法:

圖片86.png
圖片87.png

代碼演示:

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = getServletContext();
        servletContext.setAttribute("hehe", "呵呵");
        String hehe = (String) servletContext.getAttribute("hehe");
        System.out.println("hehe:"+hehe);
        servletContext.removeAttribute("hehe");
        String hehe2 = (String) servletContext.getAttribute("hehe");
        System.out.println("hehe:"+hehe2);
    }

效果:

hehe:呵呵
hehe:null

1.2讀取全局(整個(gè)項(xiàng)目)配置參數(shù)(讀取項(xiàng)目在web.xml中的配置信息)

我們?cè)趙eb.xml文件中是可以配置項(xiàng)目的初始化信息:
項(xiàng)目的配置信息需要在當(dāng)前這個(gè)web.xml的全局位置配置:

圖片88.png

需求: 設(shè)置項(xiàng)目全局參數(shù) 公司=極客營(yíng) 地址=常武中路888號(hào)
1 在web.xml中配置全局(項(xiàng)目)參數(shù)信息

圖片89.png

2 根據(jù)key獲取value

圖片90.png

1.3ServletContext讀取Web工程中資源文件路徑

要讀取資源,必須先找到這個(gè)文件:
第一個(gè)要介紹的方法是:


圖片91.png
String realPath = context.getRealPath("/WEB-INF/classes/c3p0-config.xml");
System.out.println(realPath);

效果:

C:\apache-tomcat-7.0.81\webapps\aa\WEB-INF\classes\c3p0-config.xml
//使用IO讀取展示到控制臺(tái):
BufferedReader reader = new BufferedReader(new FileReader(new File(realPath)));
String line = null;
while((line = reader.readLine()) != null){
    System.out.println(line);
}

解析獲取到的資源的文件類型:

圖片92.png
ServletContext context = getServletContext();       
String realPath = context.getRealPath("/WEB-INF/classes/c3p0-config.xml");
System.out.println(context.getMimeType(realPath));      
String realPath2 = context.getRealPath("/1.html");      System.out.println(context.getMimeType(realPath2));
//效果:
application/xml
text/html

第2章response介紹(服務(wù)器 ——>客戶端瀏覽器)

在之前學(xué)習(xí)servlet的時(shí)候,我們已經(jīng)可以處理請(qǐng)求和響應(yīng),針對(duì)請(qǐng)求和響應(yīng),我們servlet方法中提供了request對(duì)象和response對(duì)象,方便我們使用。

今天,我們主要來學(xué)習(xí)和使用response對(duì)象:

圖片93.png

ServletResponse定義了基本的響應(yīng)數(shù)據(jù)的方法,但是不面對(duì)任何協(xié)議。

圖片94.png

2.1response的狀態(tài)碼和響應(yīng)頭設(shè)置

設(shè)置狀態(tài)碼:


圖片95.png

int sc 是狀態(tài)碼(200,302,404,500),不要設(shè)置不存在的響應(yīng)狀態(tài)碼
默認(rèn)是200;

設(shè)置響應(yīng)頭信息:

圖片96.png

name : 表示響應(yīng)頭 name的值
value : 響應(yīng)頭對(duì)應(yīng)的值

2.2常用的響應(yīng)頭演示:

2.2.1Refresh: 3;url=http://(頁面自動(dòng)刷新)

3 表示是的時(shí)間,3秒
url 地址
到3秒后,頁面刷新url
測(cè)試代碼:

response.setHeader("Refresh", "5;url=http://www.jd.com");

2.2.2Location: http://

通常告知瀏覽器 馬上向該地址發(fā)送請(qǐng)求 通常 和 302 一起使用!!
(重點(diǎn)) 結(jié)合302完成重定向 操作 Location重定向后地址

代碼演示一:

response.setStatus(302);
response.setHeader("Location", " http://localhost:9090/day02/1.html ");

代碼演示二:

response.sendRedirect("http://localhost:9090/day02/1.html ");

重定向的細(xì)節(jié):


圖片97.png

瀏覽器發(fā)送了兩次請(qǐng)求,第一次請(qǐng)求中:

圖片98.png

指定了讓瀏覽器再次發(fā)送請(qǐng)求的地址

請(qǐng)求轉(zhuǎn)發(fā)和重定向的區(qū)別:

圖片99.png

重定向和轉(zhuǎn)發(fā)的區(qū)別:
1 轉(zhuǎn)發(fā)操作發(fā)生在服務(wù)器內(nèi)部,重定向是瀏覽器執(zhí)行操作
2 轉(zhuǎn)發(fā)地址欄不變,重定向,地址欄變化
3 轉(zhuǎn)發(fā)在一次請(qǐng)求中完成,重定向是兩次請(qǐng)求
4 轉(zhuǎn)發(fā)可以在一次請(qǐng)求中共享數(shù)據(jù),重定向不行。

2.2.3Content-Type: text/html; charset=utf-8

告訴瀏覽器以什么樣的方式打開資源,和使用編碼集
代碼演示:

response.setContentType("text/html;charset=utf-8");
response.getWriter().write("<h1>哈哈哈<h1>");
~~
效果:
哈哈哈

如果設(shè)置普通文本形式:text/plain

response.setContentType("text/plain;charset=utf-8");
response.getWriter().write("<h1>哈哈哈<h1>");

效果:
<h1>哈哈哈</h1>

2.3設(shè)置響應(yīng)體

應(yīng)用場(chǎng)景: 瀏覽器顯示的內(nèi)容, 下載文件等.
response 以流的形式,將內(nèi)容輸出給瀏覽器
response.getWriter() 獲取響應(yīng)體的字符輸出流,輸出頁面的時(shí)候使用
response.getOutputStream() 獲取響應(yīng)體的字節(jié)輸出流,輸出文件(圖片,avi等。。。。)的時(shí)候使用

通過這兩個(gè)流可以向?yàn)g覽器輸出 響應(yīng)體內(nèi)容.

注意問題:
1 文件數(shù)據(jù)傳輸: getOutputStream 手動(dòng)生成響應(yīng)內(nèi)容時(shí) 使用 getWriter
2 getOutputStream 和 getWriter 相互排斥,不能同時(shí)使用,否則會(huì)沖突.
3 tomcat會(huì)自動(dòng)調(diào)用response輸出流的 close方法和flush方法, 因此不需要我們手動(dòng)關(guān)閉流.

2.3.1需求: 向?yàn)g覽器輸出一個(gè)百度的超鏈接 的html頁面

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 需求: 向?yàn)g覽器輸出一個(gè)百度的超鏈接 的html頁面
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().println("<html>");
        response.getWriter().println("<head><title>百度超鏈接</title></head>");
        response.getWriter().println("<body>");
        response.getWriter().println("<a );
        response.getWriter().println("</body>");
        response.getWriter().println("</html>");
    }

頁面效果:

圖片100.png

2.4下載介紹

2.4.1下載方式介紹

文件的下載有2種方式可以完成:
1、超鏈接形式:
<a href=”資源的路徑” >資源名稱</a>
問題:
1 中文文件名亂碼
2 圖片和文本直接解析而不是下載
3 只有rar壓縮文件,才直接下載
2、使用Servlet通知瀏覽器下載:
1 修改請(qǐng)求路徑,將要下載的文件名稱,發(fā)送給服務(wù)器的servlet,讓servlet進(jìn)行處理
2 加載服務(wù)器上的文件資源
3 提示瀏覽器,以下載的方式,獲取服務(wù)器資源
4 使用IO的方式,將文件數(shù)據(jù)輸出到瀏覽器(response.getOutputStream();)

2.4.2服務(wù)器端寫程序下載(重點(diǎn):必須掌握

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        // 1.獲取下載的文件名
        String fileName = request.getParameter("fileName");
        //fileName = new String(fileName.getBytes("iso-8859-1"), "utf-8");
        

        // 2.獲取資源在服務(wù)器上的位置
        ServletContext context = config.getServletContext();
        String dir = context.getRealPath("/WEB-INF/file");
        File file = new File(dir, fileName);

        // 3.告知瀏覽器,打開對(duì)話框
        // Content-Type 設(shè)置文件媒體格式
        response.setContentType(context.getMimeType(fileName));
        
        // 處理中文文件名亂碼
        // 谷歌
        fileName = URLEncoder.encode(fileName, "utf-8");
        //fileName=new String (fileName.getBytes("iso-8859-1"),"utf-8");
        
        // Content-Disposition 設(shè)置要被下載的文件名
        response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
        
        
        // 4.使用IO技術(shù),將數(shù)據(jù)發(fā)送(使用response對(duì)象發(fā)送數(shù)據(jù))
        // 獲取輸入流
        FileInputStream ins = new FileInputStream(file);
        // 獲取輸出流
        ServletOutputStream out = response.getOutputStream();
        byte[] buf = new byte[8192];
        int len = 0;
        while ((len = ins.read(buf)) != -1) {
            out.write(buf, 0, len);
        }
        ins.close();
    }


<body>
    <a href="DownLoadServlet?fileName=cat.jpg">cat.jpg</a>
    <a href="DownLoadServlet?fileName=2.jpg">2.jpg</a>
    <a href="DownLoadServlet?fileName=3.txt">3.txt</a>
    <a href="DownLoadServlet?fileName=heidisql.rar">heidisql.rar</a>
    <a href="DownLoadServlet?fileName=極客營(yíng).txt">極客營(yíng).txt</a>
</body>

注意:如果MyEclipse10.0無法使用BASE64Encoder這個(gè)類(無法導(dǎo)入這個(gè)包),按一下方式解決。
解決方法:按照如下方法設(shè)置Eclipse導(dǎo)入%JAVA_HOME%\jre\lib目錄下的rt.jar包即可,Project->Properties,選擇Java Build Path設(shè)置項(xiàng),再選擇Libraries標(biāo)簽,Add External Jars添加%JAVA_HOME%\jre\lib\rt.jar就可以使用
如果還是不行,可以再修改項(xiàng)目的JDK,將JDK版本改成本地安裝的JDK版本

小結(jié):
1)先修改頁面——發(fā)送要下載的文件的文件名

圖片101.png

2)定位要被下載的文件的位置(獲取文件名的時(shí)候,處理中文亂碼問題)
3)設(shè)置文件的媒體格式
4)解決中文文件名問題(先要判斷瀏覽器,根據(jù)不同的瀏覽器,不同編碼處理)
5)設(shè)置要被下載的文件名
6)使用IO技術(shù)將數(shù)據(jù)發(fā)送給瀏覽器(response獲取的out輸出流,不用手動(dòng)關(guān)閉,自己使用的輸入流,需要手動(dòng)關(guān)閉)

附錄:學(xué)員問題解答

問題1 :ServletContext的getContext(),getContextPath(),getRealPath() 以及HttpServletRequst的getContextPath(),getRequestURI() getRequestURL() getServletPath() 這些方法獲得路徑有什么區(qū)別和聯(lián)系
答: ServletContext
getContext() :獲取指定路徑的項(xiàng)目,它的ServletContext對(duì)象,但是,處于安全考慮,如果獲取其他的項(xiàng)目ServletContext都會(huì)拿到null,所以方法不常用
getContextPath():獲取當(dāng)前項(xiàng)目根路徑
getRealPath():獲取當(dāng)前項(xiàng)目中,指定資源的路徑

HttpServletRequst:
getContextPath():獲取當(dāng)前項(xiàng)目根路徑(同上)
getRequestURI(): 獲取請(qǐng)求地址,不包含協(xié)議,地址,端口
getRequestURL(): 獲取請(qǐng)求地址,包含協(xié)議,地址,端口

問題2 :ServletContext 與Servlet的在服務(wù)器中存在形式被稱為什么? 使用ServletContext會(huì)出現(xiàn)并發(fā)問題么?如何解決
答:1 對(duì)象
ServletContext tomcat在底層的實(shí)現(xiàn)類是org.apache.catalina.core.ApplicationContextFacade,這是一個(gè)容器存取數(shù)據(jù)的
Servlet 是處理請(qǐng)求和響應(yīng)的對(duì)象,由我們自己實(shí)現(xiàn)
2 ServletContext對(duì)象在存取數(shù)據(jù)的時(shí)候使用ConcurrentHashMap,線程安全。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,590評(píng)論 19 139
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong閱讀 22,943評(píng)論 1 92
  • 一、Servlet概述 1.sun公司提供的動(dòng)態(tài)web資源開發(fā)技術(shù)。本質(zhì)是上一段java小程序,要求這個(gè)小程序必須...
    devstrongzhao閱讀 320評(píng)論 0 0
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,814評(píng)論 11 349
  • 那個(gè)蘋果的故事 去學(xué)校新建的機(jī)房,雪白的墻壁上赫然掛著圖靈的圖片。原諒我的孤陋寡聞,記住他除了他的一系列的頭銜,還...
    為為道來閱讀 220評(píng)論 0 0

友情鏈接更多精彩內(nèi)容