JavaWeb學習篇—Servlet基本配置及http協議

目錄

一、什麼是Servlet

二、使用IDEA創建一個servlet程序全過程圖解:

關於映射路徑:

三、servlet的執行流程:

3.1 引入概念  容器

什麼是容器:

容器可以用來幹嘛:

3.2 Servlet的執行流程:

四、http協議:

4.1 常見的請求頭:

4.2常見的響應頭:

4.3 通過servlet獲取http請求信息:

4.3.1 獲取請求行的信息

4.3.2 獲取請求頭基本信息

4.3.3 獲取表單參數的值

4.3.4  非法鏈接

4.4 通過servlet獲取http響應信息

4.4.1 重定向 

4.4.2  定時刷新

4.4.3  設置響應類型

4.4.4  以下載的格式打開


一、什麼是Servlet

Servlet是Java Servlet的簡稱。Java Servlet 是運行在web服務器上的應用程序,簡單來說,其實它就是一個類,能夠被web服務器解析的一類。

總的來說,servlet的功能主要就是幹兩件事:

  • 接收客戶端的請求;
  • 響應服務器的響應

servlet遵循的是網絡協議中的 http協議 ;

剛開始可以這麼理解servlet的作用 :

二、使用IDEA創建一個servlet程序全過程圖解:

首先,在官網下載一個Tomcat:

解壓後,進入裏面的bin目錄,找到對應的啓動文件:

windows下的啓動文件是startup.bat

linux下的啓動文件爲startup.sh:

啓動一下,保證可以運行(不會閃退):

 

如果閃退的話,可能是你沒有配JAVA_HOME環境變量(網上有步驟),或者下的Tomcat的版本有問題也可能導致閃退。

然後就可以在IDEA下手動創建一個Servlet程序:

首先,創建一個空的maven項目

然後步驟就是正常創建項目的步驟...

然後在pom文件中將打包設置爲war包

接下來補全目錄結構:web項目的目錄結構爲:在main下面創建一個webapp,在webapp下面創建目錄WEB-INF,在WEB-INF中創建一個web.xml文件:

在補一下web.xml文件中的內容(直接在Tomcat安裝目錄裏的WEB-INF裏面的web.xml文件中將下面部分的內容複製過來在最後補一個</webapp>就行了,如下圖):

或者直接複製這個:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">
    <!--配置網站信息-->
    
</web-app>

web.xml是servlet的配置文件,Servlate裏面的全局參數,監聽器,過濾器都是在這裏面,所以非常重要,怎麼用後面再說!!!

然後再pom文件中導入Servlet需要的jar包:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

然後在:Run -> Edit Configurations--> 點左上角的 + -->然後在下拉框找到Tomcat server  --> 選擇Local(表示本地) --> 然後name裏面自己填一個名字,在Application server裏面找到自己下載的Tomcat,這時右下角如果有一個紅色感嘆號的警告,點fix,選擇 xxxWar,然後點擊應用,並確定,這樣我們的Tomcat就算是配好了,具體過程如下圖:

 

確定之後:

然後點apply 然後OK。到這裏我們就可以創建Servlet項目了。

這時候在我們自己的包下創建一個servlet:

這個時候如果 左下角那個對號點不了,就重新導一下maven項目,如下圖:

創建好了之後,web.xml中會報錯,如下:

現在,要在web.xml中寫上:

關於映射路徑:

作用:在運行servlet的時候,首先它就會來web.xml文件中找對應的映射路徑,找到了纔可以運行

寫法:

  • 精確匹配:/xxx
  1. /hello  ——> http://localhost:8080/hello
  2. /fei/hello  ——> http://localhost:8080/fei/hello
  • 模糊匹配 
  1. /* 任意路徑
  2. *,html 前面必須是任意路徑,但是後面必須以指定後綴名結束
  • 最後:要注意不能即出現精確匹配又出現模糊匹配(例如:/hello/* 就是一種錯誤寫法【前面是精確匹配,後面是模糊匹配】)
  • 也不能只寫一個 / ,因爲在Tomcat的web.xml中的缺省路徑就是一個 / ,如果在當前的wen.xml中找不到對應的動態資源文件,就會使Tomcat中的缺省路徑介入程序。

優先級比較:

  • 精確匹配的優先級高於模糊匹配,在模糊匹配中,任意路徑的優先級高於以指定後綴結尾的路徑

再來看看新建的這個servlet的類,裏面默認覆寫兩個方法:

  • doGet(requset, response)   表示 以get方式提交信息
  • doPost(requset, response)   表示已post方式提交信息

一般情況下,我們常用doGet(), 在doPost中直接調用doGet就可以了。

簡單的使用案例:第一個servlet

點擊運行之後,由於我們這裏沒有配主頁,進來之後再瀏覽器會報錯(404 ),不過對於練習使用案例來說並不影響什麼。

這時候在地址欄輸入剛剛在web.xml中配置的:

回車之後就有東西了:

那麼要在瀏覽器輸入中文,要先設置編碼爲utf-8:

其實上面的setContentType中的ContentType就是http協議請求頭中的東西,我們可以在剛剛那個界面按F12(我用的瀏覽器是按F12,別的不清楚)就可以看到http 請求頭 / 響應頭 中的詳細信息:

從上面的方法我們可以看出,servlet好像和我們之前寫的程序不太一樣,它裏面main方法,但是也可以執行,那麼servlet到底是怎麼執行的呢???

三、servlet的執行流程:

3.1 引入概念  容器

什麼是容器:

從上面的步驟來看,我們會發現servlet和我們平時寫的程序不太一樣,因爲它沒有main方法,也可以執行,但是在以前不是說main方法是程序執行的入口嗎,那爲啥servlet就可以例外了呢;因爲servlet程序受控於另外一個java應用,這個應用就是容器,servlet程序就是在這個叫容器的東西里面運行的。在剛開始我們說的要下載的Tomcat,就是常見的容器中的一種,常見的還有 Jetty。

容器可以用來幹嘛:

容器是用來管理和運行servlet的

  • 通信支持:利用容器提供的方法,能夠輕鬆讓servlet與web服務器對話,無需自己建立ServerSocket,監聽接口,吃昂見流等操作。容器知道自己與web服務器之間的協議,所有Servlet不必擔心Web服務器Web服務器(如 Apache,Nginx)與自己的Web之間的API,只需要考慮實現業務即可。
  • 生命週期管理:容器控制着Servlet的生死。它會負責加載類,實例化,和初始化Servlet,調用Servlet的方法,並使Servlet實例能夠被垃圾回收。有了容器的控制,開發者就不需要考慮過多的資源管理。
  • 多線程支持:容器會自動的爲它接收到的每一個Servlet請求創建一個新的java線程。針對客戶端請求,如果Servlet已經運行了完全相應的HTTP服務方法,該線程就會結束。這些並不意味着開發者不用考慮線程安全問題,它同樣會遇到同步問題。不過,由於服務器來創建和管理多線程來處理多個請求,開發者同樣會省去不少的工作。
  • 聲明方式實現安全:利用容器,可以使用XML部署描述文件來配置安全性(Servlet3,0開始可以使用註解方式來描述),而不必將其硬編碼寫到Servlet或其他類中。
  • JSP支持:容器可以將JSP代碼翻譯成Java代碼。

3.2 Servlet的執行流程:

  1. 在瀏覽器地址欄輸入:http://localhost:8080/hello ( 以 /hello 爲例 ),接下來,它會在網站配置web.xml中找到是否存在一個映射 url-pattern:/hello
  2. 如果找到,找對應的Servlet名稱:HelloServlet,在配置信息中找是否存在一個同名的Servlet
  3. 通過反射獲取到HelloServlet.class類對象
  4. 反射機制獲取到裏面的無參構造/成員方法/ ---->由Tomcat解析裏面的內容
  5. 使用HTTPServletResponse響應給用戶內容
  6. 如果第二步中在web.xml中沒有找到對應的映射路徑,就在webapp下尋找靜態資源,如果還沒有找到,就報404錯誤。

四、http協議:

4.1 常見的請求頭:

 

Accept 瀏覽器接受的數據類型
Accept-Charset 瀏覽器接受數據編碼格式
Accept-Encoding 瀏覽器接受的數據壓縮格式
Accept-Language 瀏覽器接受的語言  
Host 請求發出的主機和端口(必須)
If-Modified-Since 瀏覽器緩存的最後修改時間
Referer 當前請求來自於哪裏 (防止非法鏈接)
User-Agent 當前用戶的瀏覽器類型
Cookie 瀏覽器保存的cookie數據(會話管理)
Connection

瀏覽器和服務器的連接狀態。

close:關閉。keep-alive:保持連接

Date 請求發出的時間

 

 

 

 

 

 

 

 

 

 

 

 

4.2常見的響應頭:

Location 重定向的地址。結合302狀態使用完成重定向的效果
Server 服務器的類型
Content-Encoding 服務器發送給瀏覽器的數據壓縮格式
Content-Length 服務器發送給瀏覽器的數據長度
Content-Language 服務器支持的語言
Content-Type 服務器發送給瀏覽器的數據類型和數據編碼格式
Last-Modified 服務器資源的最後修改時間
Refresh 定時刷新或者每隔n秒天真資源
Content-Disposition 以下載方式打開資源
Set-Cookie 服務器發送給瀏覽器的cookie數據
Expires(-1)

通知瀏覽器不使用緩存

Connection

(close/Keep-Alive)

連接狀態
Date 響應發出時間

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4.3 通過servlet獲取http請求信息:

4.3.1 獲取請求行的信息

請求行:請求行由3部分組成

  • 請求方法:get/post/...
  • 資源的uri
    • uri 和 url不一樣 ,url 是 uri 的子集
    • uri是映射路徑  :/myFirstServlet
    • url是統一資源定位符:http://localhost:8080/myFirstServlet
  • 協議及版本
    • http的版本:
    • http1.0 只能請求一次
    • http1.1 可以反覆請求

代碼獲取:

運行結果:

4.3.2 獲取請求頭基本信息

運行結果:

4.3.3 獲取表單參數的值

首先,寫一個簡單的html的form表單如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>title</title>
</head>
<body>
<h5>get提交方式</h5>
<form action="/RequsetDemo" method="get">
    用戶名:<input type="text" name="userName"> <br/>
    密&nbsp;&nbsp;&nbsp;碼:<input type="password" name="password"> <br/>

    性別:
    <input type="radio" name="gender" value="男">男
    <input type="radio" name="gender" value="女">女 <br>
    愛好:
    <input type="checkbox" name="hobby" value="zuqiu">zuqiu
    <input type="checkbox" name="hobby" value="piqiu">piqiu
    <input type="checkbox" name="hobby" value="pingpang">pingpang
    <input type="checkbox" name="hobby" value="paobu">paobu
    <input type="checkbox" name="hobby" value="papo">papo <br>

    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" value="提交">
</form>
<hr/>
<h5>post提交方式</h5>
<form action="/RequsetDemo" method="post">
    用戶名:<input type="text" name="userName"> <br/>
    密&nbsp;&nbsp;&nbsp;碼:<input type="password" name="password"> <br/>

    性別:
    <input type="radio" name="gender" value="男">男
    <input type="radio" name="gender" value="女">女 <br>
    愛好:
    <input type="checkbox" name="hobby" value="zuqiu">zuqiu
    <input type="checkbox" name="hobby" value="piqiu">piqiu
    <input type="checkbox" name="hobby" value="pingpang">pingpang
    <input type="checkbox" name="hobby" value="paobu">paobu
    <input type="checkbox" name="hobby" value="papo">papo <br>

    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" value="提交">
</form>
</body>
</html>

運行結果爲:

get 和 post 方式提交的數據,其獲取方法完全不一樣,獲取參數的方式如下:

  • 獲取通過get方式提交的參數:
    • 調用 getQueryString()方法獲取(Tomcat8.0以上的版本不用解決亂碼問題,在內部已經對編碼問題解決了)
  • 獲取通過post方式提交的參數:
    • 通過InputStream流讀取參數(post方式需要解決亂碼問題)

也有一種通用的獲取參數的方式:

  • requset.getParameter(String name)    返回 String value
  •  requset getParameterNames()        返回 Enurmation / Iterator 迭代器

使用案例:

get方式:

運行結果:

post方式:

運行結果:

通用方式獲取:

運行結果:

 

4.3.4  非法鏈接

非法鏈接指的是

  1. 直接訪問下載地址的情況 referer = null;
  2. referer 請求頭中不包含廣告頁面 : referer.contains("adv.html");  其中adv.html是廣告頁面

運行結果:

現在在webapp目錄下用HTML寫一個簡單的廣告頁面adv.html :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>adv</title>
</head>
<body>
廣告鏈接...
<a href="/GetReferer">跳轉到資源地址</a>
</body>
</html>

然後再來試試獲取referer

運行結果:

4.4 通過servlet獲取http響應信息

4.4.1 重定向 

實現方式1:

  1. 設置響應狀態碼:response.setStatus(302);
  2. 設置響應頭:response.setHeader("location"," * .html");

實現方式2:

  1. response.sendRedirect("/ *. html") ;

運行結果:

4.4.2  定時刷新

  • response.setHeader("refresh", “1”) ; // 表示每隔一秒刷新一次
  • response.setHeader("refresh", “3;*.html”) ; // 表示格3秒跳轉到指定html頁面

4.4.3  設置響應類型

這個在上面已經用過了,比如:來在瀏覽器輸出中文的時候不會亂碼

   response.setHeader("content-type", "text/html;charset=utf-8");
   ==》簡寫方式:
   response.setContentType("text/html;charset=utf-8");

運行結果:

 

4.4.4  以下載的格式打開


response.setHeader("Content-Disposition", "attachment;filename="+file.getName());
public class DownLoadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws
            ServletException, IOException {
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
            ServletException, IOException {
//        1、創建一個File對象
        File file = new File("D:\\圖片\\1.jpg"); //這個是要下載的文件
//        2、設置響應頭
        response.setHeader("Content-disposition", "attachment;filename="+file.getName());
//        3、創建一個字節流輸入對象
        InputStream in = new FileInputStream(file);
//        4、獲取字節輸出流對象
        OutputStream out = response.getOutputStream();
//        5、定義一個緩衝數組
        byte[] buff = new byte[1024];
//        6、邊讀邊寫
        int len = 0;
        while ((len=in.read(buff)) != -1)
        {
            out.write(buff, 0, len);
        }
//        7、關閉資源
        in.close();
        out.close();
    }
}

 

運行結果: 下載文件

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