超通俗易懂的Servlet入門教程

不怕千萬人阻擋,就怕本身投降。html


文章目錄


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


01.Servlet快速入門

1.建立javaEE項目java

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

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

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

<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方法。apache

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);

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

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

相關文章
相關標籤/搜索