超通俗易懂的Servlet入門教程

不怕千萬人阻擋,就怕自己投降。


文章目錄


概念:運行在服務器端的小程序
servlet就是一個接口,定義了Java類被瀏覽器訪問到(tomcat識別)的規則。將來我們自定義一個類,實現servlet接口,複寫方法。所以servlet就是實現了Servlet接口的類。


01.Servlet快速入門

1.創建javaEE項目

2.定義一個類,實現servlet接口
public class servletDemo1 implements servlet

3.實現接口中的抽象方法

4.配置Servlet,在xml中配置。

<servlet><servlet-name>demo1</ servlet-name><servlet-class>cn.itcast.web. servlet.ServletDemo1</servlet-class>< / servlet><servlet-mapping><servlet-name>demo1</ servlet-name><url-pattern>/demo1</url-pattern>< / servlet-mapping>

執行原理:
1,當服務器接受到客戶端瀏覽器的請求後,會解析請求uRL路徑,獲取訪問的servlet的資源路徑2.查找web.xml文件,足否有對應的<url-pattern>標籤體內容。
3.如果有,則在找到對應的<servlet-class>全類名
4. tomcat會將字節碼文件加載進內存,並且創建其對象
5,調用其方法。



servlet中的生命週期方法∶
1.被創建:執行init方法,只執行一次
對象被創建後再執行Servlet方法。

servlet什麼時候被創建?

默認情況下,第一次被訪問時,servlet被創建。可以配置其執行servlet的創建時機。

<servlet>標籤下配置

1,第一次被訪問時,創建
<load-on-startup>的值爲負數。

2.在服務器啓動時,創建
<load-on-startup>的值爲0或正整數。

Servlet的init方法,只執行一次,說明一個servlet在內存中只存在一個對象,Servlet是單例的。

多個用戶同時訪問時,可能存在線程安全問題。

解決∶儘量不要在servlet中定義成員變量。即使定義了成員變量,也不要對修改值。

2.提供服務:執行service方法,執行多次。

每次訪問Servlet時,Service方法都會被調用一次。

3.被銷燬:執行destroy方法,只執行一次。

servlet被銷燬時執行,服務器關閉時,Servlet被銷燬。

只有服務器正常關閉時,纔會執行destroy方法。

destroy方法在servlet被銷燬之前執行,一般用於釋放資源。

02.Servlet3.0註解配置

java6支持Serlet3.0.

java8支持Serlet4.0.

好處:支持註解配置。

可以不需要web.xml。

步驟:
1.創建JavaEE項目,選擇Servelt3.0以上的,可以不創建web.xml。

2.定義一個類,實現Servlet接口。

3.複寫方法。

4.在類上使用@WebServlet註解,進行配置。

因爲註解是加在類上的,所以不需要關心類名,只需要關心資源路徑。

@WebServlet(urlPatterns="/demo")//可以配置多個路徑public class ServletDemo implement Servlet{}

或者

@WebServlet("/demo")//可以配置多個路徑public class ServletDemo implement Servlet{}

IDEA與tomcat的相關配置
1.IDEA會爲每一個tomcat部署的項目單獨建立一份配置文件.
查看控制檯的log : Using CATALINA_BASE:“c: \users\fay.Intelli]Idea2018.1\system\tomcatl_itcast"

2.工作空間項目和 tomcat部署的web項目。

tomcat真正訪問的是"“tomcat部署的web項目”",“tomcat部署的web項目"對應着”"工作空間項目”的web目錄下的所有資源。

WEB-INF目錄下的資源不能被瀏覽器直接訪問。

03.GenericServlet&HttpServlet(Serlvet的體系結構)

GenericServlet是Servlet的子類(子);
HttpServlet是GenericServlet的子類(孫);

問題提出:有時候我們只需要重寫Servlet的service方法。然而我們繼承Servlet類必須實現Servlet的所有抽象方法。這樣就與我們意願相左。有什麼解決辦法呢?

解決辦法】:GenericServlet爲Servlet的子類,並且已經(空)實現了Servlet的4個方法,只有service方法沒有實現。

因此我們可以寫一個類,繼承GenericServlet抽象類。實現service方法即可。

將來我們在定義自己的serlvet類時,可以繼承抽象類GenericServlet即可,如果需要使用到其他方法,重些該方法即可。

可以看出,此時代碼書寫已經很方便,但是我們以後開發並不使用這種方式。

那我們使用哪種方式呢?

【HttpServlet】:爲什麼要使用這個類呢?
那我們得問自己,我們實現service方法幹嘛呢?

我們在寫service方法體時,需要判斷前端給後臺的請求方式,並根據其獲取數據。每次都需要判斷,有沒有一種方式,可以簡潔的達到效果呢?
HttpServlet抽象類,幫我們把這些事情都做好了,我們只需要重寫HttpServlet對應得方法即可。
如:

doGet(){//重寫部分};doPost(){//重些部分};

因此我們將來需要屏蔽請求方式的處理邏輯,繼承HttpServlet就顯得格外好用。

HttpSerlvet:對http協議的一種封裝,簡化操作
因此我們以後開發:就不再定義類繼承GenericServlet實現service方法。而是定義類繼承HttpServlet重寫doGet(),或doPost()方法。

Servlet的urlpartten配置
因爲urlpattten是一個數組,所以可以爲其配置多個資源路徑

@WebServlet({"/d4","dd4","ff"})public class ServletDemo extends HttpServlet{}

一個servlet可以設置多個訪問路徑。
路徑的定義規則

1./xxx2./xxx/xxx(多層路徑)(/xxx/*)


3.*.do

04.HTTP

概念:Hyper Text Transfer Protocol超文本協議。
傳輸協議:定義了,客戶端和服務器端通信超時,發送數據的格式。

請求和響應一一對應
無狀態:每次請求之間相互獨立,不能交互數據。
歷史版本:
1.0:每一次請求響應都會建立新的連接(http1.0)
1.1:複用連接(http1.1)。



請求消息數據格式
1.請求行
請求方式 請求url 請求協議/版本
GET /index.html HTTP/1.1


HTTP協議有7種請求方式。
GET
(1.請求參數在請求行中,在url後。
(2.請求的url的長度有限制。
(3.不安全
POST:
(1.請求參數在請求體中。
(2.請求的url的長度沒有限制。
(3.相對安全







2.請求頭
請求頭名稱:請求頭值
常見的請求頭:
主機
User-Agent:瀏覽器告訴服務器,我訪問你使用的瀏覽器版本信息,可以獲取其信息解決瀏覽器兼容性問題。



Accept:告訴服務器,我可以解析的格式。

Referer:告訴服務器,當前請求從哪裏來。
作用:方式其他人盜鏈。統計工作。

Connection:表示連接可以複用。

3.請求空行
空行(分割POST的請求頭和請求體)
4.請求體
POST纔有請求體,封裝了POST的請求參數。


響應消息數據格式

1.響應行
協議及版本 響應狀態碼 狀態碼描述

狀態碼:
1xx:服務器接收客戶端消息,但沒有接收完成,等待一段時間後,發送1xx狀態碼。
2xx:成功

3xx:302(重定向),304訪問緩存
在這裏插入圖片描述
4xx:客戶端錯誤,405沒有對應的方法。(doGet,doPost)

5xx:服務器端錯誤,500代碼錯誤,505服務器不支持客戶端使用的HTTP版本。

2.響應頭
頭名稱:值
常見的響應頭:
Content-Type:服務器告訴客戶端本次響應體數據格式以及編碼格式。
Content-disposition:服務器告訴客戶端以什麼格式打開響應體數據。
值:in-line默認值,在當前頁面內打開。
attachment:以附件形式打開響應體,文件下載。
3.響應空行






4.響應體
傳輸的數據。

05.Request對象

1.request對象繼承體系結構:
ServletRequest —接口
繼承
HttpServletRequest —接口
實現
org.apache.catalina.connector.RequestFacade 類(tomcat實現了HttpServletRequest接口)




2.request和response的原理

在這裏插入圖片描述
1.request和response對象是由服務器創建的。我們只是使用他們。

2.request對象是來獲取請求消息,response對象是來設置響應消息。

3.request的功能

3.1獲取請求消息數據

獲取請求行數據

**1.1獲取請求方式**

String getMethod();//瞭解即可

**1.2獲取虛擬目錄**

String getContextPath();//重要

**1.3獲取Servlet路徑:**

String getServletPath();

**1.4獲取get方式請求參數:**

String getQueryString();//瞭解

**1.5獲取請求URI**

String getRequestURI(); 如:/day1/demo2

**1.6獲取請求URL**

StringBuffer getRequestURL(); 如: http://localhost/day1/demo2

**1.7獲取協議及版本**

String getProtocol();

**1.8獲取客戶機的IP地址**

String getRemoteAddr();

URI:統一資源標識符。(範圍更大)
URL:統一資源定位符。
獲取請求頭數據

String getHeader(String name);//通過請求頭的名稱獲取請求頭的值
Enumeration<String>  getHeaderNames();//獲取所有的請求頭名稱
@WebServlet("/ServletTest2")public class ServletTest2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //獲取所有請求頭名稱
        Enumeration<String> headNames = request.getHeaderNames();
        //遍歷
        while (headNames.hasMoreElements()){
            String name = headNames.nextElement();
            //根據名稱獲取請求頭的值
            String value = request.getHeader(name);
            System.out.println(name+"---"+value);
        }
    }}

獲取請求體數據
步驟:
1.獲取流對象

BufferedReader getReader() ;//獲取字符輸入流,只能操作字符數據
ServletInputStream getInputStream();//獲取字節輸入流,可以操作所有
類型的數據(文件上傳)

2.再從流對象中拿數據

@WebServlet("/ServletTest3")public class ServletTest3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //獲取請求參數
        //1.獲取字符流
        BufferedReader br = request.getReader();
        //讀取數據
        String line = null;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }}

3.2.其他功能
1.獲取請求參數的通用方式(get和post都可以)

String getParameter(String name):根據參數名獲取參數值
String[] getParameterValues(String name):根據參數名獲取參數值的數組
(常用於複選框)
Enumeration<String> getParameterNames():獲取所有請求參數名稱。
Map<String,String[]> getParameterMap():獲取所有參數的map集合。

優勢:屏蔽了get和post方法的不同,代碼只需要寫一份,再另一方法中調用另一個已經實現的方法即可,滿足get和post請求。

獲取請求參數中文亂碼的問題處理:
get方式:tomcat8已經將get方式亂碼問題解決了。
post方式:會亂碼。

解決方案:在獲取參數前,設置流的編碼。
request.setCharacterEncoding(“utf-8”);

//設置編碼request.setCharacterEncoding("utf-8");//獲取請求參數String username = request.getParameter("username");

2.請求轉發
在這裏插入圖片描述

一種在服務器內資源跳轉的方式。
步驟:

1.通過request對象獲取請求轉發器對象:
RequestDispatcher getRequestDispatcher(String path)2.使用RequestDispatcher對象來進行轉發:forward(ServletRequest request,ServletResponse response)

特點
瀏覽器地址欄路徑沒有發生變化。

只能訪問當前服務器內部資源中。

轉發是一次請求,多個資源使用同一個請求。
3.共享數據
在這裏插入圖片描述

域對象:一個有作用範圍的對象,可以在範圍內共享數據。
request域:代表一次請求的範圍,一般用於請求轉發的多個資源中共享數據。
方法:

setAttribute(String name,Object obj);存儲數據
Object getAttitude(String name);通過鍵獲取值removeAttribute(String name)通過鍵移除值

例子:

@WebServlet("/ServletTest4")public class ServletTest4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ServletTest4被訪問了");
        //存儲數據到request域中
        request.setAttribute("name","MengYangchen");
        RequestDispatcher getquestDispatcher = request.getRequestDispatcher("/ServletTest5");//沒有虛擬路徑(項目)
        getquestDispatcher.forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
    }}
@WebServlet("/ServletTest5")public class ServletTest5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ServletTest5被訪問了");
        //獲取數據
        Object name = request.getAttribute("name");
        System.out.println(name);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }}

結果:
在這裏插入圖片描述

4.獲取ServletContext(對象)
返回ServletContext對象

ServletContext getServletContext()

06.Request案例(登錄)

用戶登錄案例需求:
1.編寫login.html登錄頁面
username &password兩個輸入框

2.使用Druid數據庫連接池技術,操作mysql,day14數據庫中user表

3.使用JdbcTemplate技術封裝JDBC

4.登錄成功跳轉到SuccessServlet展示:登錄成功!用戶名,歡迎您

5.登錄失敗跳轉到FailServlet展示:登錄失敗,用戶名或密碼錯誤。

07.Response對象

1.請求消息:客戶端發送給服務器的數據。
2.服務器端發送給客戶端的數據。

功能:設置響應消息。
1.設置響應行。

void setStatus(int sc)  設置狀態碼

2.設置響應頭。

void setHeader(String name, String value)

3.設置響應體。
獲取輸出流

PrintWriter getWriter()  字符輸出流
ServletOutputStream getOutputStream()  字節輸出流

使用輸出流,將數據輸出到客戶端瀏覽器。

Response案例

1.完成重定向
在這裏插入圖片描述

@WebServlet("/ServletResponseTest1")public class ServletResponseTest1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("response1被訪問了");
        //重定向,訪問ServletResponseTest1,會自動跳轉到ServletResponseTest2
        //1.設置狀態碼302/*        response.setStatus(302);
        //2.設置響應頭location
        response.setHeader("location","/First/ServletResponseTest2");
        */

        //簡單重定向方法
        response.sendRedirect("/First/ServletResponseTest2");//有虛擬路徑
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }}
@WebServlet("/ServletResponseTest2")public class ServletResponseTest2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("response2被訪問了");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }}

轉發的特點:
1.轉發地址欄路徑不變。
2.轉發只能訪問當前服務器下的資源。
3.轉發是一次請求。
4.路徑不需要帶虛擬路徑。
重定向的特點:
1.地址欄發生改變。
2.重定向可以訪問其他站點(服務器)的資源。
3.重定向是兩次請求。
4.路徑需要虛擬路徑。








2.服務器輸出字符數據到瀏覽器
亂碼原因:編碼解碼用的編碼不同。
在這裏插入圖片描述

2.1.獲取字符輸出流。

//設置輸出流編碼response.setCharacterEncoding("utf-8");//告訴瀏覽器,服務器發送消息體數據的編碼,建議瀏覽器使用該編碼解碼response.setHeader("content-type","text/html;charset=utf-8");//簡單形式,設置編碼response.setContentType("text/html;charset=utf-8");PrintWrite out = response.getWriter();//tomcat返回的對象[ISO-8859-1]。

2.2輸出數據(不需要刷新)
out.write();

3.服務器輸出字節數據到瀏覽器
3.1獲取字節輸出流

3.2輸出數據

response.setContentType("text/html;charset=utf-8");ServletOutputStream out = response.getOutputStream();out.writer("你好".getBytes("utf-8"));

4.驗證碼
1.本質:圖片
2.目的:防止惡意表單註冊。
隨機生成。
後端:servlet:



@WebServlet("/IdentifyingCodeServlet")public class IdentifyingCodeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int width = 100;
        int height = 50;
        //1.創建一對象,在內存中的圖片(驗證碼圖片對象)
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        //2.美化圖片
        //2.1填充背景色
        Graphics g = image.getGraphics();
        g.setColor(Color.pink);
        g.fillRect(0,0,100,50);//填充矩形

        //2.2畫邊框
        g.setColor(Color.yellow);
        g.drawRect(0,0,width-1,height-1);

        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        //生成隨機角標
        Random ran  = new Random();

        for(int i=1;i<=4;i++){
            int index = ran.nextInt(str.length());
            char ch = str.charAt(index);//隨機字符
            //2.3寫驗證碼
            g.setColor(Color.blue);
            g.drawString(""+ch,width/5*i,height/2);
        }
        //2.4畫干擾線,防識別
        //隨機生成座標點
        for(int i=0;i<8;i++){
            int x1 =ran.nextInt(width);
            int x2 =ran.nextInt(width);
            int y1 =ran.nextInt(height);
            int y2 =ran.nextInt(height);
            g.setColor(Color.green);
            g.drawLine(x1,y1,x2,y2);
        }

        //3.將圖片輸出到頁面展示
        ImageIO.write(image,"jpg",response.getOutputStream());
  

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }}

前端頁面:

<body><h1>賬號註冊</h1><form action="/First/ServletTest3" method="post">
    <input type="text" placeholder="請輸入用戶名" name="username"><br>
    <input type="password" placeholder="請輸入密碼" name="password"><br>
    <input type="submit"  value="註冊"><br>
    <img id="checkCode" src="/First/IdentifyingCodeServlet"/>
    <a id="change" href="">看不清換一張</a></form>
    <script>
        //1.給超鏈接或圖片綁定單擊事件
        //2.重新設置圖片的src屬性
        window.onload = function () {

            var a  =document.getElementById("change");
            //1.獲取圖片對象
            var img  = document.getElementById("checkCode");
            //2.綁定單擊事件
            img.onclick = function () {
                //加時間戳
                var date = new Date().getTime();

                img.src = "/First/IdentifyingCodeServlet?"+date;//欺騙緩存,因爲路徑不變,瀏覽器會自動去找緩存,而不是服務器
            }
            a.onclick = function () {
                var date = new Date().getTime();
                img.src = "/First/IdentifyingCodeServlet?"+date;//欺騙緩存,因爲路徑不變,瀏覽器會自動去找緩存,而不是服務器
            }
        }
    </script></body>

路徑的分類

1.相對路徑
如:./index.html
不以/開頭,以./開頭的路徑(可以省略不寫)。
規則:找到當前資源和目標資源之間的相對位置關係。
./表示當前目錄;…/上一級目錄。
2.絕對路徑
如:http://localhost/First/ServletResponseTest2
簡略寫法:/First/ServletResponseTest2
以/開頭。
規則:判斷定義的路徑是給誰用的。
1.給客戶端瀏覽器使用:需要加虛擬目錄(超鏈接…項目的訪問路徑)
2.給服務器端使用(轉發…不需要加虛擬目錄)
【問題提出】在重定向寫路徑是我們採用的是直接書寫路徑,以後一旦更改了虛擬目錄。所有代碼將需要該過來。











【解決方案】動態獲取虛擬目錄。

//動態獲取虛擬目String contextPath = request.getContextPath();//簡單的重定向方法response.sendRedirect(contextPath+"ServletResponseTest2");

前端代碼採取jsp獲取虛擬目錄。

08.ServletContext對象

1.概念:代表整個web應用,可以和程序的容器(服務器)來通信。

2.如何獲取ServletContext對象。

1.通過request獲取
request.getServletContext();2.通過HttpServlet獲取this.getServletContext();//因爲我們繼承了HttpServlet

兩者獲取的ServletContext是相等的。

2.功能:
獲取MIME類型。
MIME類型:在互聯網通信過程中定義的一種文件數據類型。
格式:大類型/小類型 text/html


//通過HttpServlet獲取SevletContext context = this.getServletContext();//定義文件名稱String filename = "a.jpg";//獲取MIME類型String mimeType = context.getMimeType(filename);System.out.println(mimeType);

域對象:共享數據。

1.setAttribute(String name,Object value)2.getAttribute(String name)3.removeAttribute(String name);

ServletContext對象範圍:所有用戶所有請求的數據。

@WebServlet("/ServletContextTest")public class ServletContextTest extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通過httpServlet獲取
        ServletContext context  = this.getServletContext();

        //設置共享數據
        context.setAttribute("name","Is me!");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }}
@WebServlet("/ServletContextTest2")public class ServletContextTest2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通過httpServlet獲取
        ServletContext context  = this.getServletContext();

        //獲取共享數據
        Object a = context.getAttribute("name");
        response.setContentType("utf-8");
        PrintWriter out = response.getWriter();
        out.print(a);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }}

訪問http://localhost/First/ServletContextTest2得到結果:
在這裏插入圖片描述

獲取文件的真實路徑
在web服務器的真實路徑。
在這裏插入圖片描述

1.方法:String getRealPath(String path)

配置文件所在地方不同,參數書寫不同。

String realPath = context.getRealPath("/a.txt");//web目錄下資源訪問String realPath = context.getRealPath("/WEB-INF/a.txt");//WEB-IN目錄下資源訪問String realPath = context.getRealPath("/WEB-INF/classes/a.txt");//src目錄下資源訪問
@WebServlet("/ServletContextTest3")public class ServletContextTest3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String realPath = context.getRealPath("/WEB-INF/classes/a.txt");
        System.out.println(realPath);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }}

09.文件下載案例

文件下載需求

1.頁面顯示超鏈接

2.點擊超鏈接後彈出下載提示框

3.完成圖片文件下載。
分析:
1.超鏈接指向的資源如果能過被瀏覽器解析,則在瀏覽器中顯示,如果不能解析,則彈出下載提示框。不滿足需求。

2.任何資源都必須彈出下載提示框。

3.使用響應頭設置資源的打開方式。

步驟:
1.定義頁面,編輯超鏈接href屬性,指向servlet,傳遞資源名稱filename

2.定義servlet
2.1獲取文件名稱
2.2使用字節輸入流加載文件進內存.
2.3指定response的響應頭:content-disposition:attachment;filename=xxx.2.4將數據寫出到response輸出流。


前端:

<body><p align="center">優質資源網站</p><a href="/First/res/img/1.jpg">表情包(未處理)</a><br><a href="/First/ServletDownLoad?filename=1.jpg">表情包</a><br><a href="/First/ServletDownLoad?filename=2.jpg">表情包2</a></body></html>

後端:

@WebServlet("/ServletDownLoad")public class ServletDownLoad extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.獲取請求參數,文件名稱
        String filename = request.getParameter("filename");
        //2.使用字節輸入流加載文件進入內存
        //2.1找到文件服務器路徑
        ServletContext context = this.getServletContext();
        String realPath = context.getRealPath("/res/img/"+filename);
        //2.2用字節流關聯
        FileInputStream fis = new FileInputStream(realPath);

        //3.設置reponse響應頭
        //設置響應數據類型:context-type
        String mimeType = context.getMimeType(filename);
        response.setHeader("content-type",mimeType);
        //設置打開方式:content-disposition
        response.setHeader("content-disposition","attachment;filename="+filename);

        //4.將輸入流的數據寫出到輸出流中
        ServletOutputStream sos = response.getOutputStream();
        byte[] buff = new byte[1024*4];
        int len =0;
        while ((len=fis.read(buff))!=-1){
            sos.write(buff,0,len);
        }
        fis.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }}

中文文件名的問題
【解決思路】
1.獲取客戶端使用的瀏覽器版本信息
2.根據不同的版本信息,設置filename不同的編碼方式。


//1.獲取user-agent請求頭String agent = request.getHeader("user-agenet");//2.使用工具類方法編碼文件名(自己從網上下載工具欄導入在自己創建的工具包)filename = DownLoadUtils.getFileName(agent,filename);

別害怕顧慮,想到就去做,這世界就是這樣,當你把不敢去實現夢想的時候夢想就會離你越來越遠,當你勇敢地去追夢的時候,全世界都會來幫你。

在這裏插入圖片描述
在這裏插入圖片描述


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